在Mac上汇编和在linux上汇编有什么区别?

时间:2013-11-01 02:56:57

标签: macos gcc assembly x86 x86-64

我一直在努力熟悉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_startprocLtmp2:这样的“奇怪”的东西在机器指令的中间轻拍,没有任何意义。

我不知道去哪里找出它们是什么以及它们的含义。我准备拔头发,因为我几个月来一直试图为初学者找到一个好资源。有什么建议吗?

2 个答案:

答案 0 :(得分:14)

首先,您将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函数名称的下划线,.L vs L作为标签(目标)。 OS X的汇编程序理解'.p2align'指令。 .align 4, 0x90基本上做同样的事情。

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

答案 1 :(得分:1)

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

Mac代码肯定是64位代码。

这是主要区别。

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