装配程序,带有未签名/签名的部门

时间:2015-10-20 04:44:32

标签: assembly masm

我正在尝试编写一个简单的汇编程序,将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,则问题就会消失。

任何人都可以解释原因吗?

我知道分裂的唯一条件是股息必须是除数的两倍。还有其他我想念的东西吗?

1 个答案:

答案 0 :(得分:5)

const是一个字节。当您执行IDIV byte_divisor时,商将被放置在AL中,并且范围为-128到127. 1000/5是200,这不在允许的范围内。如果你使用DIV,则商的范围是0到255,这就是为什么你的例子适用于那种情况。

如果你想要IDIV 1000乘5,你应该使用16位除数。但是,您需要记住,在使用IDIV r/m16时,您实际划分的是由DXAX组成的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