2015-10-20 23 views
1

我想寫一個簡單的裝配程序除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

任何人都可以解釋爲什麼嗎?

我知道除法的唯一條件是股息必須是除數的兩倍。還有什麼我失蹤?

回答

5

const是一個字節。當你做IDIV byte_divisor時,商將被放置在AL中,並且具有-128到127的範圍。1000/5是200,這不在允許的範圍內。如果使用DIV,商的範圍是0到255,這就是您的示例在這種情況下工作的原因。

如果你想IDIV 1000乘5你應該使用一個16位除數。但是需要注意的是,當使用IDIV r/m16時,實際上劃分的是由DXAXDX保存最高有效位,而AX最低有效位)組成的32位雙字。

從Intel的手冊:

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之前,你應該從AX價值創造DX:AX一個符號雙。有一個名爲CWD所做的正是這一個指令:

CWD指令 複製標誌在AX寄存器中的值轉換成DX寄存器的每個位的(第15位)。

即:

.data 
const dw 5 ; now a word 

.code 
mov ax,1000 
cwd   ; sign-extend ax into dx 
idiv const 
; quotient is in ax, remainder in dx 
+0

完美。謝謝! –