2

位置に依存しないコードに関するこの記事を読んでいて、この関数のアセンブリ リストに遭遇しました。

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(:::);

4

1 に答える 1