我试图弄清楚8086微处理器的imul和idiv指令是如何工作的。
我知道这个: 1. mul和div是无符号数的乘法和除法 2. imul和idiv,也是乘法和除法,但对于有符号数字
我搜索了所有的网络,以及我刚才写的内容,这是我发现的唯一信息,但是以不同的方式编写。
我有这个:
mov AX, 0FFCEh
idiv AH
因为它是一个字节,AL = AX / AH(结果)和AH =余数
在指令之后我得到 AX = 0032h ,显然是0余数,结果是32.有人可以解释它是如何得到这个结果的吗?我需要知道如何解释指令是如何工作的(逐位)。
与imul指令相同。
我有:
mov AX, 0FF10h
imul AL
因为AL是一个字节,乘法的结果将保存到AX中。在执行imul指令 AX = 0100h 之后,为什么它不是F100h?
我不知道CPU究竟是如何实现mul,div,imul和idiv的。如果有人可以向我说明差异,我会非常感激。
谢谢!
答案 0 :(得分:1)
维基百科的二进制乘法文章解释了比特级细节,has a section about signed multiply。你可以找到类似的比特级细节。
但就像汉斯所说的那样,你真的不需要了解细节来解决这个问题。你需要知道,与add / sub不同,mul和div的按位运算对于2的补码整数与无符号整数是不同的,而不仅仅是对结果的解释。有趣的事实:对于乘法,the lower half of the full-width result is the same for mul and imul。
因此,您只需要指导参考手册对指令操作的描述,并了解例如: -1的2's complement表示为0xFF。 (请参阅http://www.felixcloutier.com/x86/或英特尔原创PDF:x86代码wiki中的链接)
以与指令相同的方式解释每个操作数中的位,并进行数学运算"通常"。 e.g。
AX = 0xFFCE => -2^16 + 0xFFCE = -0x32 = -50
AH = 0xFF => -1
-50 / -1 = 50, no remainder
答案 1 :(得分:0)
您所遇到的问题部分在评论中阐明。
mov AX, 0FFCEh
idiv AH
将FFCE除以FF。值得庆幸的是,这是签名部门,否则会引发错误。
乘法更容易:
mov AX, 0FF10h
imul AL
将AL * AL的结果存储在AX中。
注意大于字节的乘法和除法;他们也使用DX寄存器。
答案 2 :(得分:0)
mov AX, FFCE
idiv AH
<强> AX 强> = FFCE
<强> AH 强> = FF
否定的定义是他们排名最高的位等于1,所以 FFCE是否定的,
,因为 1 111 1111 1100 1110
并且处理器无法使用底片, 我们需要有积极的,这意味着我们否定这个数字(或者处理器根据排名最高的位自动执行此操作)
NEG FFCE
或
1111 1111 1100 1110 =>
=> 0000 0000 0011 0001 +1 =>
=> 0000 0000 0011 0010 =>
=> 0032h
然后下一个 - AH寄存器是FF - 也是负数 我们需要正面版本,我们否定
1111 1111 =>
=> 0000 0000 +1 =>
=> 0000 0001 =>
=> 01h
然后当所有数字都是正数时,我们计算除法
32h div 1h,0h余数=&gt; AL,32h result =&gt; AH
两者都是否定的,这意味着结果是积极的,不需要更多转换。
mov AX, FF10
imul AL
<强> AL 强> = 10H
imul / mul在参数为8bit时使用AL(它是)
所以imul AL与
相同AL * AL => 10h * 10h => 0100h = AX
mov AX, FF10
imul AH
<强> AH 强> = FF
<强> AL 强> = 10H
所以现在我们有AL * AH =&gt; AX
AL = 10h
AH = FF是负数,我们需要正数,我们否定并得到=&gt; 01H
积极的乘法
10h * 01h => 0010h
但由于其中只有一个是否定的,我们必须否定结果, 不要丢失起始零,否则你的答案将不正确
0010h => FFEF +1 => FFF0 = AX