最近在学习《微机原理与接口技术》,被里面的各种信号,引脚,指令搞得焦头烂额,虽然以前学过组成原理,模电数电,然而一是基本忘却,二是当时水平也只是初窥门径。今将研究idiv指令的结果记录之,以备将来查验。
一、上机环境
win10,DOSBox 0.74
二、div指令简介
这个不用我怎么说了吧,都懂。
三、div手算结果
1. 先看一段汇编代码
mov ax,100D
mov bl,50D
div bl
答案应该没有悬念,ax的值确实为0002H
2. 再看一段汇编代码(注意:换成idiv了)
mov ax,-100D
mov bl,50D
idiv bl
ax的值为00FEH
ax的低位是商,-2的补码是就是FEH,原来汇编程序全程使用了补码进行运算
在经过汇编后,汇编程序就已经将-100D转换成了FF9CH,-100的补码是9CH,好家伙,汇编程序居然还自动帮我们CBW了?
看下图运算结果,商确实是用补码表示的
如果把idiv改成div会怎么样?!FF9CH除以32H,商为51CH,al放不下啊,咋办?系统会调用div异常中断,除0或者商溢出都会调用此中断。来带你看看。
老规矩,先确认一遍代码
然后单步调试到div bl 指令,看看之后会发生什么
执行完div bl之后并没有执行mov ah,4c,而是执行了"??? [BX+SI]"这个鬼
这就是除法错误中断服务程序的代码!来,追根溯源一下
翻开某本相关教科书
在执行除法指令DIV或IDIV后,除数为0或商超过了存放它的目标寄存器所能表示的范围时,除法出错。
这时除法指令就相当于一个中断源,它向CPU发出中断类型号为0的中断,自动执行0型中断服务程序。
中断向量表存放在内存空间最开始的1KB的地方,中断类型号为0的终端服务程序的入口地址就放在0000:0000H ~ 0000:0003H,其中前两个字节存的是IP,后两个字节存的是CS
看 上图“??? [BX+SI]”指令的地址:F000:1060,走,去看看0000:0000H是不是这两个数
实锤了!! ,好吧,这也没有太高兴的。
写了这么多,终于可以开始总结div指令的手算方法了。
看这道题:
已知:
mov ax,0FFBDH
mov bx,12F8H
idiv bl
则此指令片段执行后,ax为___,bx为____。
抽象出它的考点:其实就是补码运算而已...。先看除法指令,用的是idiv,那么0FFBDH和12F8H必定都是某个数的补码形式,否则这除法还有啥意思是吧。你再细品,高位为什么为FF?,这不是跟我们刚刚讲的一样嘛,低位为BDH,大于等于80H,所以高位扩展为FFH。这道题并没有用CBW指令,而是直接把两条指令融合了。所以看到这里该知道怎么算了吧。
1. 还原法
根据推算,被除数的补码应该是BDH(1011 1101),把BDH看成有符号数,原码是多少呢?1100 0011,十进制真值为-67
除数为F8H,也看成有符号数,十进制真值为-8
商为8,余数为-3(符号与被除数相同),换成十六进制补码形式,ax的值为FD 08H
2.我丢,我竟然没找到第二种方法,麻烦好心人评论区告知一下
那么div指令呢?div指令直接算就完事儿了!你觉得它会怎么样它结果就是怎样的,这叫符合直觉的设计。