我正在尝试编写一个简单的汇编程序,将1000除以5,但我的程序冻结了系统。
该计划如下,
include pcmac.inc
.model Small
.586
.stack 100h
.data
const db 5
Main PROC
_Begin
mov AX, 1000
idiv const // Problem line
_Exit 0
Main ENDP
End Main
如果我使用未签名的分部div
而不是已签名的分部idiv
,则问题就会消失。
任何人都可以解释原因吗?
我知道分裂的唯一条件是股息必须是除数的两倍。还有其他我想念的东西吗?
答案 0 :(得分:5)
const
是一个字节。当您执行IDIV byte_divisor
时,商将被放置在AL
中,并且范围为-128到127. 1000/5是200,这不在允许的范围内。如果你使用DIV
,则商的范围是0到255,这就是为什么你的例子适用于那种情况。
如果你想要IDIV
1000乘5,你应该使用16位除数。但是,您需要记住,在使用IDIV r/m16
时,您实际划分的是由DX
和AX
组成的32位双字({{1}保持最高有效位,DX
最低有效位。)
来自英特尔的手册:
AX
因此,在IDIV r/m16 Signed divide DX:AX by r/m16, with result stored in AX ← Quotient, DX ← Remainder.
IF OperandSize = 16 (* Doubleword/word operation *)
THEN
temp ← DX:AX / SRC; (* Signed division *)
IF (temp > 7FFFH) or (temp < 8000H)
(* If a positive result is greater than 7FFFH
or a negative result is less than 8000H *)
THEN
#DE; (* Divide error *)
ELSE
AX ← temp;
DX ← DX:AX SignedModulus SRC;
之前,您应该根据IDIV
中的值在DX:AX
中创建一个有符号的双字。有一条名为AX
的指令就是这样做的:
CWD
指令 将CWD
寄存器中值的符号(第15位)复制到AX
寄存器中的每个位位置。
即:
DX