Xcode汇编器:如何使其识别callq %rax直接调用指令?
让Xcode汇编器识别
callq %rax的方法 Xcode默认使用的LLVM汇编器对x86-64汇编语法有严格要求,必须显式标记间接调用类型,因此不再接受callq %rax这种写法。要让汇编器支持该语法,可采用以下两种方案:
方案1:切换到GNU汇编器(GAS)
Xcode允许通过编译选项切换到系统自带的GNU汇编器,它兼容callq %rax的写法:
- 打开Xcode项目的Build Settings
- 找到Assembler Flags(如果是在C/C++文件中嵌入汇编,可修改Other C Flags)
- 添加编译选项
-no-integrated-as
添加后,Xcode会调用GNU汇编器处理代码,即可直接使用callq %rax指令。
方案2:用宏适配LLVM汇编器语法
如果不想切换汇编器,可以定义宏来兼容新旧语法,同时适配LLVM的要求:
.macro call_reg reg .ifdef __APPLE__ callq *%\reg .else callq %\reg .endif .endm
在代码中将callq %rax替换为call_reg rax即可——宏会在苹果平台自动转换为LLVM接受的callq *%rax,其他平台保持原有语法。
补充说明
在x86-64架构中:
callq %rax(或LLVM要求的callq *%rax)是寄存器间接调用,直接跳转到rax寄存器存储的地址执行callq *(%rax)是内存间接调用,先读取rax指向的内存地址,再跳转到该地址执行
两者语义不同,注意不要混淆。
内容的提问来源于stack exchange,提问作者Karl Bergeron
相关产品推荐
相关产品推荐

