AT&T汇编push指令操作数类型不匹配错误求助
AT&T汇编「operand type mismatch for `push'」错误排查
核心原因分析
AT&T语法中push指令对操作数的大小匹配要求严格,常见触发错误的场景:
- 未指定指令后缀(如
pushl/pushq),汇编器无法推断操作数大小 - 操作数大小与指令后缀不匹配(比如用
pushl操作64位寄存器/内存) - 内存操作数未明确标注大小(如直接
push (%eax)而未指定pushl (%eax))
针对性解决步骤
1. 强制指定指令后缀
AT&T语法中,push必须明确操作数宽度:
- 32位操作:用
pushl - 64位操作:用
pushq - 16位操作:用
pushw
错误示例:
push %rax ; 未指定后缀,汇编器可能默认32位,与64位寄存器不匹配 push (rbx) ; 内存操作数未指定大小
修正后:
pushq %rax pushq (rbx)
2. 寄存器加载后的匹配问题
如果已经把内存加载到寄存器仍报错,检查:
- 寄存器宽度与
push后缀是否一致:比如把32位内存加载到%eax,要用pushl %eax而非pushq %eax - 是否误写寄存器名:AT&T中寄存器名必须带
%,不能漏写(如push eax是错误的,必须push %eax)
3. 内存操作数的大小标注
直接push内存时,必须明确内存宽度:
; 错误:未指定内存大小 push my_var ; 正确:根据变量大小指定后缀 pushl my_var ; 若my_var是32位 pushq my_var ; 若my_var是64位
示例代码修正参考
假设你的代码中有类似片段:
.data my_var: .long 0x12345678 .text .global _start _start: push my_var ; 错误:未指定大小 movl my_var, %eax push eax ; 错误:寄存器名漏写%
修正后:
.data my_var: .long 0x12345678 .text .global _start _start: pushl my_var ; 指定32位后缀 movl my_var, %eax pushl %eax ; 补全%,指定32位后缀
编译验证
用gas编译时,建议加上-m32或-m64明确架构,避免默认模式冲突:
as -m64 your_code.s -o your_code.o ld your_code.o -o your_code
内容的提问来源于stack exchange,提问作者user28774630
相关产品推荐
相关产品推荐

