Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 具有未签名/签名除法的汇编程序_Assembly_Masm - Fatal编程技术网

Assembly 具有未签名/签名除法的汇编程序

Assembly 具有未签名/签名除法的汇编程序,assembly,masm,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

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

有人能解释为什么吗

我所知道的除法的唯一条件是,除数必须是除数的两倍。我还缺少什么吗?

常量是一个字节。当您使用IDIV byteu除数时,商将放在AL中,其范围为-128到127。1000/5等于200,这不在允许的范围内。如果您使用DIV,则商的范围是0到255,这就是您的示例在这种情况下工作的原因

如果您想将IDIV1000乘以5,则应该使用16位除数。但您需要记住,在使用IDIV r/m16时,实际上您要划分的是32位双字,由DX和AX 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;
const是一个字节。当您使用IDIV byteu除数时,商将放在AL中,其范围为-128到127。1000/5等于200,这不在允许的范围内。如果您使用DIV,则商的范围是0到255,这就是您的示例在这种情况下工作的原因

如果您想将IDIV1000乘以5,则应该使用16位除数。但您需要记住,在使用IDIV r/m16时,实际上您要划分的是32位双字,由DX和AX 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;