Linux x86汇编调用syscall write输出字符串异常问题求助
问题根因
- 内存读写宽度不匹配导致越界:
num仅分配1字节存储空间,你使用32位寄存器eax执行mov eax, [num]时,会一次性读取从num起始的4字节数据,连带读取了其后msg的前3字节内容。后续执行mov [ecx], eax时,又将4字节内容写入仅2字节长的val数组,直接覆盖了val后的num、msg前2字节的原有数据,这就是bye!打印异常的核心原因——原字符串的开头被越界写操作篡改。 - 输入数据类型处理逻辑错误:
read系统调用读取到的是输入字符的ASCII码,比如输入9实际存入num的是十进制57(对应字符9的ASCII值),你直接减4刚好得到ASCII码5属于巧合,逻辑上缺少ASCII转数字、计算后转回ASCII的步骤。 - 硬编码长度易出错:手动指定打印长度容易出现数值不匹配问题,推荐用汇编常量自动计算字符串长度。
修复后代码
segment .data val: ; 2字节存储数组:存结果字符+换行 db 0 db 0 num db 0 ; 存储输入的1字节字符 msg db 'bye!', 0ah ; 结尾打印的字符串+换行 msg_len equ $ - msg ; 自动计算msg的长度,避免硬编码错误 segment .text global _start ; 程序入口点 _start: ; 调用read读取用户输入的1个字符 mov ecx, num mov edx, 1 mov ebx, 0 mov eax, 3 int 80h ; 处理输入:ASCII转数字→减4→转回ASCII mov al, [num] ; 仅读取1字节的输入字符到8位寄存器al sub al, '0' ; 将ASCII码转换为实际数字 sub al, 4 ; 执行减4操作 add al, '0' ; 将计算结果转回ASCII码用于打印 ; 将结果写入val数组 mov ecx, val mov [ecx], al ; 仅写入1字节的结果字符 inc ecx mov [ecx], byte 0ah ; 追加换行符 ; 调用write打印计算结果 mov ecx, val mov edx, 2 ; 结果字符1字节+换行1字节,共2字节 mov ebx, 1 mov eax, 4 int 80h ; 调用write打印bye! mov ecx, msg mov edx, msg_len mov ebx, 1 mov eax, 4 int 80h ; 调用exit退出程序 mov eax, 1 int 80h
内容的提问来源于stack exchange,提问作者mikaela.md
相关产品推荐
相关产品推荐

