8086汇编编译报错A2070无效指令操作数排查与修复
x86汇编A2070报错修复方案
错误根因
触发SUB.asm (169) : error A2070: invalid instruction operands的直接原因是违反了x86汇编指令的基础规则:
MOV指令不支持内存操作数直接到内存操作数的传输,你写的MOV RESFINALASCII, BYTE PTR [DI]中,RESFINALASCII是数据段中定义的内存标号,[DI]也是通过寄存器间接寻址的内存操作数,即便加了BYTE PTR做类型声明,这种写法本身就是语法非法的。- 这行代码的逻辑本身也完全错误:调用
CONVDEC过程时,你已经把DI初始化为RESFINALASCII的首地址,过程执行中会逐字节把转换好的ASCII字符写入缓冲区,过程返回时DI已经指向缓冲区最后一个写入字符的下一位置,指向的是未初始化的随机内存值,把这个值复制到缓冲区首地址没有任何实际意义,属于冗余错误代码。
代码关联问题排查
除了直接触发报错的代码行,你的程序还有几个会导致功能异常的隐性bug:
CONVDEC过程未初始化DX寄存器:16位DIV BX指令默认使用DX:AX拼成32位被除数,你进入过程前仅给AX赋值,DX中的残留值会导致除法计算结果完全错误;且每次除法循环后也需要清空DX,否则余数会被当成高16位参与下一次运算。CONVDEC生成的字符串是逆序的:通过取余法得到的数字是从最低位到最高位的,直接存入缓冲区后字符顺序颠倒,直接输出会得到反向的数字。- 流程未触发要求的PROC转换逻辑:当前代码运算完成后直接跳转到
AFFRES段用手写的栈逻辑输出,完全没有调用CONVDECIMAL段的转换代码,不符合作业要求。 - 非法输入分支无处理:
HORSCODE1、HORSCODE2标签下没有跳转指令,用户输入非数字字符后程序会继续向下执行乱序代码。
修复方案
- 直接删除第169行的错误MOV语句,这行代码无任何有效作用,是报错的直接来源。
- 修正
CONVDEC过程,补全寄存器初始化和字符串结束符,修正后代码如下:CONVDEC PROC MOV BX,0AH XOR DX,DX ; 进入除法前清空DX CONVDECBCL: DIV BX ADD DL,30H ; 用ADD比OR语义更清晰,效果一致 MOV [DI],DL INC DI XOR DX,DX ; 每次除法循环后清空DX CMP AX,0 JNE CONVDECBCL MOV BYTE PTR [DI], '$' ; 追加DOS字符串输出需要的$结束符 RET CONVDEC ENDP - 调整程序执行流程:把加减乘除四个运算分支末尾的
JMP AFFRES改成JMP CONVRES,新增CONVRES段处理转换和输出:CONVRES: LEA DI,RESFINALASCII MOV AX,RESULTAT CALL CONVDEC ; 此处可添加字符串逆序逻辑,修正CONVDEC生成的倒序字符 LEA DX,RESFINALASCII MOV AH,09H INT 21H JMP FIN - 给
HORSCODE1、HORSCODE2添加跳转指令,输入非法字符时跳回对应数字输入的提示位置,避免程序跑飞。
内容的提问来源于stack exchange,提问作者Nathan Arkxv
相关产品推荐
相关产品推荐

