You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 17:39:03