GCC内联汇编问题:asm("push eax;")无法正常工作,求解决方案
GCC内联汇编中
push eax失效的解决建议 核心原因
在x86_64架构的64位编译模式下,GCC默认采用AT&T汇编语法,直接使用push eax(Intel语法风格)或未指定操作数大小的push %eax会出现兼容性问题——64位模式下32位寄存器的push指令需要显式指定操作数长度,而ax(16位)、rax(64位)属于架构原生支持的操作数宽度,因此能正常执行。
可行解决方法
使用AT&T语法的显式操作数后缀
按照GCC默认的AT&T语法规则,32位push指令需要加上l后缀,寄存器名前加%符号,写法为:asm("pushl %%eax;");(注:双
%是GCC内联汇编中寄存器的转义写法)切换到Intel语法执行指令
如果习惯Intel语法,可在汇编块内临时切换语法,执行完后切回AT&T语法避免影响其他代码:asm(".intel_syntax noprefix; push eax; .att_syntax prefix;");强制32位编译模式
如果你的程序不需要64位特性,编译时添加-m32参数,强制生成32位目标代码,此时push eax可直接按32位指令正常执行。声明寄存器修改约束
内联汇编中修改寄存器时,必须告知编译器哪些寄存器被改动,避免优化导致的异常。例如:asm volatile("pushl %%eax" : : : "memory", "%eax");volatile用于防止编译器优化掉汇编块,最后的约束列表声明了eax寄存器和内存栈被修改。
内容的提问来源于stack exchange,提问作者Christian Reinbothe
相关产品推荐
相关产品推荐

