Я читал эту статью. о позиционном независимом коде, и я столкнулся с этим списком функций на ассемблере.
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(:::);
)
-Mintel
- person Michael Petch   schedule 16.03.2019-masm-intel
в GCC. По умолчанию используется синтаксис AT&T. - person Michael Petch   schedule 16.03.2019