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

NASM x86汇编加减运算程序无需循环指针重复执行方案咨询

问题根因

  • 你注释了.bss段中num4/num5/num6/res2的定义,没有预留合法的内存空间存储第二行的运算数据,写入操作会非法覆盖其他内存,直接导致输出异常。
  • 读取单数字时指定了edx=2,会把数字后跟随的运算符、换行符一起读入,第一行输入结束的换行符会被第二组的第一个读取调用捕获,导致第二行的第一个数字没有被正确存入num4。
  • 运算逻辑存在冗余错误:你先将加法结果转ASCII存入结果变量,后续减法操作完成后没有再次转ASCII就直接存储,第一行结果正确仅为巧合。
  • 直接用mov eax, [num1]读取数值时,num1仅为1字节有效数据,会读入后续相邻内存的脏数据到eax的高位,导致运算错误。

修复方案

你不需要使用times指令,times是汇编编译期的重复展开指令,对运行期的用户输入处理没有作用。你原本直接复制第一行处理逻辑的思路是可行的,只要修复上述bug即可:

  1. 取消.bss段中第二行相关变量的注释,预留存储空间
  2. 修改单数字读取长度为1字节,每次读完数字后单独读1字节丢弃后续的运算符/换行符,避免输入内容错位
  3. 运算时仅读取1字节到al寄存器,所有数值运算完成后再统一转ASCII输出

完整可运行代码

segment .data 
    newline db 0xA, 0xD
    newlinelen equ $-newline
    
segment .bss
    num1 resb 2
    num2 resb 2
    num3 resb 2
    num4 resb 2
    num5 resb 2
    num6 resb 2
    res resb 1   
    res2 resb 1
    dump resb 1 ; 用于丢弃运算符、换行符的临时变量
    
section .text
    global main    ;must be declared for using gcc
        
main:             ;tell linker entry point
; 第一行运算处理
; 读取num1
    mov eax, 3
    mov ebx, 0  
    mov ecx, num1 
    mov edx, 1
    int 0x80
    ; 丢弃后面的运算符
    mov eax, 3
    mov ebx, 0
    mov ecx, dump
    mov edx, 1
    int 0x80

; 读取num2
    mov eax, 3
    mov ebx, 0
    mov ecx, num2 
    mov edx, 1
    int 0x80
    ; 丢弃后面的运算符
    mov eax, 3
    mov ebx, 0
    mov ecx, dump
    mov edx, 1
    int 0x80
   
; 读取num3
    mov eax, 3
    mov ebx, 0  
    mov ecx, num3 
    mov edx, 1
    int 0x80
    ; 丢弃后面的换行符
    mov eax, 3
    mov ebx, 0
    mov ecx, dump
    mov edx, 1
    int 0x80

; 第一行运算
    mov al, [num1]
    sub al, '0'
    mov bl, [num2]
    sub bl, '0'
    mov cl, [num3] 
    sub cl, '0'

    add al, bl
    sub al, cl
    add al, '0' ; 所有运算完成后统一转ASCII
    mov [res], al

; 输出第一行结果+换行
    mov eax, 4       
    mov ebx, 1
    mov ecx, res         
    mov edx, 1   
    int 0x80
    mov eax, 4
    mov ebx, 1
    mov ecx, newline
    mov edx, newlinelen
    int 0x80

; 第二行运算处理,逻辑和第一行完全一致
; 读取num4
    mov eax, 3
    mov ebx, 0  
    mov ecx, num4 
    mov edx, 1
    int 0x80
    ; 丢弃后面的运算符
    mov eax, 3
    mov ebx, 0
    mov ecx, dump
    mov edx, 1
    int 0x80

; 读取num5
    mov eax, 3
    mov ebx, 0
    mov ecx, num5 
    mov edx, 1
    int 0x80
    ; 丢弃后面的运算符
    mov eax, 3
    mov ebx, 0
    mov ecx, dump
    mov edx, 1
    int 0x80
   
; 读取num6
    mov eax, 3
    mov ebx, 0  
    mov ecx, num6 
    mov edx, 1
    int 0x80
    ; 丢弃后面的换行符
    mov eax, 3
    mov ebx, 0
    mov ecx, dump
    mov edx, 1
    int 0x80

; 第二行运算
    mov al, [num4]
    sub al, '0'
    mov bl, [num5]
    sub bl, '0'
    mov cl, [num6] 
    sub cl, '0'

    add al, bl
    sub al, cl
    add al, '0'
    mov [res2], al

; 输出第二行结果
    mov eax, 4       
    mov ebx, 1
    mov ecx, res2         
    mov edx, 1   
    int 0x80
    mov eax, 4
    mov ebx, 1
    mov ecx, newline
    mov edx, newlinelen
    int 0x80

exit:    
    mov eax, 1
    mov ebx, 0
    int 0x80

测试说明

按格式输入两行运算式即可,比如第一行输入1+2-1输出2,第二行输入3+1-2输出2,符合你的需求,不需要额外处理大于4的数字和负数的边界情况。

内容的提问来源于stack exchange,提问作者Forevar Aloen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 17:30:04