NASM x86汇编加减运算程序无需循环指针重复执行方案咨询
问题根因
- 你注释了
.bss段中num4/num5/num6/res2的定义,没有预留合法的内存空间存储第二行的运算数据,写入操作会非法覆盖其他内存,直接导致输出异常。 - 读取单数字时指定了
edx=2,会把数字后跟随的运算符、换行符一起读入,第一行输入结束的换行符会被第二组的第一个读取调用捕获,导致第二行的第一个数字没有被正确存入num4。 - 运算逻辑存在冗余错误:你先将加法结果转ASCII存入结果变量,后续减法操作完成后没有再次转ASCII就直接存储,第一行结果正确仅为巧合。
- 直接用
mov eax, [num1]读取数值时,num1仅为1字节有效数据,会读入后续相邻内存的脏数据到eax的高位,导致运算错误。
修复方案
你不需要使用times指令,times是汇编编译期的重复展开指令,对运行期的用户输入处理没有作用。你原本直接复制第一行处理逻辑的思路是可行的,只要修复上述bug即可:
- 取消
.bss段中第二行相关变量的注释,预留存储空间 - 修改单数字读取长度为1字节,每次读完数字后单独读1字节丢弃后续的运算符/换行符,避免输入内容错位
- 运算时仅读取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
相关产品推荐
相关产品推荐

