x86汇编字符串反转程序push指令报错:操作数大小未指定及无效
问题分析与解决
错误原因拆解
operation size not specified(第14行)push [eax]未指定操作数大小(字节/字/双字),汇编器无法确定从内存读取多少字节压入栈。x86指令中,内存操作数的大小必须明确声明,除非能从寄存器或指令本身推断。invalid combination of opcode and operands(修改后)
x86指令集不支持单字节的内存push操作,push指令的内存操作数只能是16位(word)或32位(dword)。这是因为栈的操作粒度按字长对齐,32位模式下栈操作默认以32位为单位。隐藏逻辑错误:
cmp eax, [msg]
此处误将内存内容(msg指向的第一个字节'c')和地址(eax中存储的字符串指针)做比较,逻辑完全错误。应直接比较地址值:cmp eax, msg。
修正后的代码
section .data msg db "ciao" len equ $ - msg section .text global _start _start: lea eax, [msg] ; eax指向字符串起始地址 mov ebx, len add eax, ebx - 1 ; eax指向字符串最后一个字符("o") reverseloop: mov dl, byte [eax] ; 将当前字符读取到dl寄存器(8位) push edx ; 压入32位的edx(低字节是目标字符,高字节补0) sub eax, 1 ; 指针向前移动一位 cmp eax, msg ; 比较当前指针是否还在字符串范围内 jge reverseloop ; 只要指针>=起始地址,继续循环 ; 可选:添加反转后字符串的输出代码 mov ecx, len printloop: pop edx mov [msg + len - ecx], dl dec ecx jnz printloop mov eax, 4 mov ebx, 1 mov ecx, msg mov edx, len int 0x80 ; 退出程序 mov eax, 1 xor ebx, ebx int 0x80
关键修正点说明
- 用
mov dl, byte [eax]读取单字节字符到8位寄存器,再通过push edx将32位寄存器内容压栈,符合x86指令集要求。 - 将
cmp eax, [msg]改为cmp eax, msg,正确比较指针地址是否在字符串范围内。 - 将循环条件
jl reverseloop改为jge reverseloop,确保遍历从最后一个字符到第一个字符的所有位置。
内容的提问来源于stack exchange,提问作者Patientes
相关产品推荐
相关产品推荐

