8086汇编32位数字打印实现及32位除10运算代码原理问询
32位数字打印代码原理解析
原有代码报错原因
8086架构下的div bx指令默认使用DX:AX组成的32位数据作为被除数,运算后商存入AX、余数存入DX。如果商的数值超过AX的16位上限(65535),会直接触发除法溢出中断,导致程序崩溃。你最初的代码直接对完整32位被除数执行div bx,只要高16位不为0,商必然超出AX容量,因此无法正常运行。
32位除10的数学逻辑
要实现32位无溢出除10,可以把32位被除数拆分为高16位H和低16位L,整个数的实际值为 H * 65536 + L,除以10的运算可以拆为两步:
- 先算高16位H除以10,得到商
Hq、余数Hr - 再将余数Hr和低16位L拼接为新的32位数
Hr * 65536 + L,除以10得到商Lq、余数R - 最终完整32位商为
Hq * 65536 + Lq,本次运算的余数就是R(范围0-9,刚好是十进制的个位数字)
这就是代码先处理高16位除法,再用余数处理低16位的核心逻辑。
正确代码逐行拆解
初始状态:DX存32位被除数高16位,AX存32位被除数低16位,BX固定为10,栈中预先压入10作为哨兵,用于后续判断打印结束。
mov bx,10 ; 固定除数为10 push bx ; 压入哨兵值10,后续判断栈是否为空 .a: mov cx,ax ; 暂存被除数低16位到CX mov ax,dx ; 把高16位放到AX,准备先算高16位除法 xor dx,dx ; 高16位本身是16位,除10时被除数为0:AX,保证不会溢出 div bx ; 高16位除10,商Hq存AX,余数Hr存DX xchg ax,cx ; 把Hq暂存到CX,同时把之前保存的低16位换回AX div bx ; DX是Hr、AX是L,刚好组成Hr*65536+L的32位被除数,除10后商Lq存AX,余数R是整个32位数除10的最终余数 push dx ; 保存余数(当前的十进制个位数字) mov dx,cx ; DX=Hq、AX=Lq,拼接为完整的32位商,作为下一轮循环的被除数 or cx,ax ; 只要Hq或Lq任意一个不为0,说明商还没到0,需要继续循环 jnz .a pop dx ; 弹出第一个有效余数(肯定是数字,商为0时才停止循环) .b: add dl,"0" ; 余数转ASCII字符 mov ah,02h ; 调用DOS中断打印字符 int 21h pop dx ; 弹出下一个栈元素 cmp dx,bx ; 如果弹出的是哨兵值10,说明所有数字打印完成 jb .b
内容的提问来源于stack exchange,提问作者raz amsily
相关产品推荐
相关产品推荐

