我一直在努力熟悉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:
这样的“奇怪”的东西在机器指令的中间轻拍,没有任何意义。
我不知道去哪里找出它们是什么以及它们的含义。我准备拔头发,因为我几个月来一直试图为初学者找到一个好资源。有什么建议吗?
答案 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特定文件格式的信息。