[英]Can someone explain what's wrong with my code and how does my teacher's code work?
這是我第一次在這里發布問題,所以我不確定這是否是正確的做法。 如果我以后應該添加更多信息,請告訴我。
我正在嘗試在 emu8086 中編寫一些代碼,我是匯編的新手,所以我還是有點困惑。 在我的作業中,對於其中一個練習,我必須編寫一個代碼來解決: r=(xy*z)/t 。 這些值是: x = 2000; y = -500; z = 200; t = 300; r =? .
我檢查了我們課程中給出的解決方案:
x dw 2000
y dw -500
z dw 200
t dw 300
r dw ?
____________________
mov ax, y
imul z
mov cx, dx
mov bx, ax
mov ax, x
cwd
sub ax, bx
sbb dx, cx
idiv t
mov r, ax
而且我不明白為什么需要使用命令cwd和sbb以及行
mov cx, dx
mov bx, ax
sbb dx, cx
這是我寫的代碼:
mov AX, y
imul z
mov BX, x
sub BX, AX
idiv t
mov r, BX
但這些是我得到的結果:
x = 07D0h
y = 0FE0Ch
z = 00C8h
t = 012Ch
r = 8E70h
( https://i.stack.imgur.com/9CU9Q.png )
r 的值應為0154h ,十進制為 340。
我想這個問題可能與乘法導致負數有關,但我不知道如何解決。
有人可以解釋這段代碼中這些指令的目的,它們如何影響整個過程以及為什么我自己的代碼是錯誤的? 除此之外,還有其他無需使用這些命令即可解決此問題的方法嗎?
先感謝您。
您看到的是使用 16 位寄存器實現 32 位算術。 這是必需的,因為計算的中間值不適合 16 位,部分原因還在於idiv
和imul
在 32 位寄存器對dx
和ax
上運行。
imul z
結果為-100000
,但不適合 16 位,並且已自動拆分為dx=0xFFFE=-2
和ax=0x7960=31072
。 做減法xy*z
x
也被擴展到 32 位,使用cwd
指令。 在此之前,臨時的y*z
被移到cx:bx
對。 減法是通過首先使用普通sub
執行低 16 位和使用sbb
執行前 16 位來傳播進位(借位)來完成的。 結果留在dx:ax
中,這是idiv
的隱式輸入。 然后在ax
中生成商。
您的代碼是錯誤的,因為sub BX, AX
將結果留在bx
中, idiv
根本沒有使用它,因為它隱式地對dx:ax
進行操作。 然后存儲那個bx
,它甚至不是 idiv 的idiv
。 您也只使用低 16 位進行計算,因此結果為2000-31072=-29072=0x8E70
。
是的,您可以使用其他指令模擬cwd
和sbb
,例如使用顯式條件跳轉。 cwd
只是將ax
符號擴展到dx
,這意味着如果ax
為負,則dx
將設置為0xffff
,否則設置為零。 您可以簡單地手動執行此操作,或者使用算術移位用符號位填充dx
,或者如果您被允許知道x
始終為正,則dx
僅為零。 而不是sbb
你可以只檢查是否有進位(借位)並從結果中減去 1 如果是的話,然后再用普通的sub
處理 rest 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.