15

我一直在尝试熟悉 mac 上的汇编,据我所知,文档非常稀少,而且大多数关于该主题的书籍都是针对 windows 或 linux 的。我以为我可以很容易地从 linux 翻译到 mac,但是这个(linux)

.file   "simple.c"
.text
.globl simple
.type   simple, @function
simple:
      pushl   %ebp
      movl    %esp, %ebp
      movl    8(%ebp), %edx
      movl    12(%ebp), %eax
      addl    (%edx), %eax
      movl    %eax, (%edx)
      popl    %ebp
      ret
.size   simple, .-simple
.ident  "GCC: (Ubuntu 4.3.2-1ubuntu11) 4.3.2"
.section        .note.GNU-stack,"",@progbits

似乎与此(mac)有很大不同

.section    __TEXT,__text,regular,pure_instructions
.globl  _simple
.align  4, 0x90
_simple:                                ## @simple
    .cfi_startproc
## BB#0:
pushq   %rbp
Ltmp2:
    .cfi_def_cfa_offset 16
Ltmp3:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp4:
    .cfi_def_cfa_register %rbp
    addl    (%rdi), %esi
    movl    %esi, (%rdi)
    movl    %esi, %eax
    popq    %rbp
    ret
    .cfi_endproc


.subsections_via_symbols

“正常”(因为没有更好的词)指令和寄存器,比如pushq %rbp别担心。但是机器指令中间的那些“奇怪”的东西.cfi_startproc没有Ltmp2:任何意义。

我不知道去哪里找出这些是什么以及它们的含义。几个月来,我一直在努力为初学者寻找一个好的资源,所以我要拔掉头发了。有什么建议么?

4

2 回答 2

17

首先,您将 32 位 x86 程序集与 64 位 x86-64 进行比较。虽然 OS X Mach-O ABI 支持 32 位 IA32,但我怀疑您需要x86-64 SysV ABI。(谢天谢地,x86-64.org网站似乎又恢复了)。Mach-O x86-64模型本质上是 ELF / SysV ABI 的变体,因此对于用户空间代码而言差异相对较小,即使使用不同的汇编程序也是如此。

这些.cfi指令是DWARF调试指令,您在汇编中并不严格需要它们 - 它们用于调用框架信息等。以下是一些最小示例:

ELF x64-64 汇编器:

    .text
    .p2align 4

    .globl  my_function
    .type   my_function,@function

my_function:
    ...
.L__some_address:

    .size    my_function,[.-my_function]

Mach-O x86-64 汇编器:

    .text
    .p2align 4

    .globl  _my_function

_my_function:
    ...
L__some_address:

除了编写 asm 教程之外,汇编器之间的主要区别是:Mach-O 函数名称的前导下划线.LL标签(目的地)的前导下划线。OS X 的汇编器理解“.p2align”指令。.align 4, 0x90基本上做同样的事情。

并非编译器生成的代码中的所有指令对于汇编器生成有效的目标代码都是必不可少的。它们需要生成堆栈帧(调试)和异常处理数据。有关更多信息,请参阅链接。

于 2013-11-01T10:48:23.110 回答
0

显然,Linux 代码是 32 位 Linux 代码。请注意,64 位 Linux 可以同时运行 32 位和 64 位代码!

Mac 代码绝对是 64 位代码。

这是主要区别。

“.cfi_xxx”行仅是用于 Mac 特定文件格式的信息。

于 2013-11-01T08:26:28.510 回答