我一直在尝试熟悉 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:
这样的“奇怪”的指令正好位于机器指令中间,没有任何意义。
我不知道到哪里去了解这些是什么以及它们的含义。我快要抓狂了,因为几个月来我一直在努力为初学者寻找一个好的资源。有什么建议吗?
最佳答案
首先,您将比较 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
与 L
。 OS X 的汇编器可以理解“.p2align”指令。 .align 4, 0x90
本质上做同样的事情。
并非编译器生成的代码中的所有指令对于汇编器生成有效的目标代码都是必需的。它们需要生成堆栈帧(调试)和异常处理数据。请参阅链接了解更多信息。
关于macos - Mac 上的汇编和 Linux 上的汇编有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19720084/