GCC使用-masm=intel编译时,变量offset触发寄存器使用错误
使用
-masm=intel编译时GNU汇编器报错"invalid use of register"的原因 问题重现
测试代码:
// test.c #include <stdio.h> size_t offset; int main(int argc, char **argv, char **envp) { offset = 20; return 0; }
编译命令及报错:
$ gcc test.c -masm=intel /tmp/ccPnqEmz.s: Assembler messages: /tmp/ccPnqEmz.s:19: Error: invalid use of register
移除赋值语句后编译正常,对比汇编代码可知,报错源于这条存储指令:
mov QWORD PTR offset[rip], 20
原因分析
GNU汇编器(GAS)的Intel语法与NASM等其他汇编器的Intel语法存在语法差异:
- NASM风格的Intel语法中,RIP相对寻址可写成
symbol[rip]; - 但GAS的Intel语法要求RIP相对寻址必须采用
[rip + symbol]的格式。
GCC在-masm=intel选项下生成的汇编代码采用了NASM风格的RIP寻址写法,GAS无法识别该格式,因此抛出"invalid use of register"错误。
解决方法
有两种可行的解决思路:
- 让GCC生成符合GAS Intel语法的代码
添加-Wa,-msyntax=intel,-mnaked-reg选项,明确告诉GAS使用Intel语法并允许裸寄存器:gcc test.c -masm=intel -Wa,-msyntax=intel,-mnaked-reg - 关闭位置无关代码生成
使用-fno-pic选项关闭位置无关代码(PIC),此时GCC会生成绝对寻址指令而非RIP相对寻址,规避语法冲突:gcc test.c -masm=intel -fno-pic
内容的提问来源于stack exchange,提问作者XiaozaYa
相关产品推荐
相关产品推荐

