位置に依存しないコードに関するこの記事を読んでいて、この関数のアセンブリ リストに遭遇しました。
0000043c <ml_func>:
43c: 55 push ebp
43d: 89 e5 mov ebp,esp
43f: e8 16 00 00 00 call 45a <__i686.get_pc_thunk.cx>
444: 81 c1 b0 1b 00 00 add ecx,0x1bb0
44a: 8b 81 f0 ff ff ff mov eax,DWORD PTR [ecx-0x10]
450: 8b 00 mov eax,DWORD PTR [eax]
452: 03 45 08 add eax,DWORD PTR [ebp+0x8]
455: 03 45 0c add eax,DWORD PTR [ebp+0xc]
458: 5d pop ebp
459: c3 ret
0000045a <__i686.get_pc_thunk.cx>:
45a: 8b 0c 24 mov ecx,DWORD PTR [esp]
45d: c3 ret
ただし、私のマシン (gcc-7.3.0、Ubuntu 18.04 x86_64) では、以下のようにわずかに異なる結果が得られました。
0000044d <ml_func>:
44d: 55 push %ebp
44e: 89 e5 mov %esp,%ebp
450: e8 29 00 00 00 call 47e <__x86.get_pc_thunk.ax>
455: 05 ab 1b 00 00 add $0x1bab,%eax
45a: 8b 90 f0 ff ff ff mov -0x10(%eax),%edx
460: 8b 0a mov (%edx),%ecx
462: 8b 55 08 mov 0x8(%ebp),%edx
465: 01 d1 add %edx,%ecx
467: 8b 90 f0 ff ff ff mov -0x10(%eax),%edx
46d: 89 0a mov %ecx,(%edx)
46f: 8b 80 f0 ff ff ff mov -0x10(%eax),%eax
475: 8b 10 mov (%eax),%edx
477: 8b 45 0c mov 0xc(%ebp),%eax
47a: 01 d0 add %edx,%eax
47c: 5d pop %ebp
47d: c3 ret
mov
私が見つけた主な違いは、命令のセマンティクスです。上のリストではmov ebp,esp
実際に に移動esp
しますebp
が、下のリストでmov %esp,%ebp
は同じことを行いますが、オペランドの順序が異なります。
手書きのアセンブリをコーディングしなければならない場合でも、これはかなり混乱します。要約すると、私の質問は、(1) 同じ命令に対して異なるアセンブリ表現を取得した理由、および (2) アセンブリ コードを記述するときに (たとえば を使用して) どちらを使用する必要があるかです__asm(:::);
。