所以我有this exact problem。
给出的解决方案是将DX
归零,但就我而言,它已经是!
我的程序是简单地将16位数字除以8位数。
我的代码是:
data segment
num1 dw 0204h
num2 db 02h
quotient db ?
remainder db ?
data ends
code segment
assume cs:code,ds:data
start: mov ax,data
mov ds,ax
mov ax,num1
div num2
mov quotient,al
mov remainder,ah
mov ah,4ch
int 21h
code ends
end start
任何解决方案?
答案 0 :(得分:3)
您非常需要开始使用空格来分隔汇编代码。这段代码正在做极简单(将一个数字除以另一个数字),但极难以阅读。显然不应该这样:简单的代码应该易于阅读!为什么难以阅读?因为你的所有样板代码都被实际执行分割操作的代码卡住了,我的眼睛只是茫然。我无法从样板中找出重要的部分。空白是免费的;不要害怕它。你的装配工并不介意。
像这样写:
data segment
num1 dw 0204h
num2 db 02h
quotient db ?
remainder db ?
data ends
code segment
assume cs:code, ds:data
start:
; Initialize Data Segment (DS)
mov ax, data
mov ds, ax
; Do the division and save the results
mov ax, num1
div num2
mov quotient, al
mov remainder, ah
; Terminate process
; (Note that you should also be setting AL to a result code here!)
mov ah, 4ch
int 21h
end start
code ends
现在,是不是更清楚什么是什么?此外,虽然MASM / TASM会让你摆脱邋,,但不要养成坏习惯。这是使您的代码不可读并获得错误结果的另一种方法。在代码中使用符号有两种不同的方法:一种方法是使用该符号的地址 / 偏移,另一种方法是使用<该符号的em> contents / value 。在MASM / TASM中,如果需要地址/偏移量,则需要使用OFFSET
关键字。当你使用内容/值时,你在技术上并不需要,但你真的应将符号包装在括号中以表明它被解除引用。换句话说,而不是:
mov ax, num1
写下来:
mov ax, [num1]
随着我的胸膛咆哮,让我们来看看你的代码有什么问题。 Michael Petch已经指出,这是另一个案例,其中MASM / TASM的“做我的意思,而不是我写的”风格并没有给你任何好处。它正在进行8位除法,因为您使用了带有num2
指令的8位操作数(DIV
)。这意味着它实际上在做:
AX / [num2]
AL
中的商和AH
中的余数。如果商大于8位,它将不适合AL
,并且除法将溢出。
解决方法是进行16位除法,在这种情况下,商将放在AX
中,其余的将放在DX
中。
为此,请编写代码:
mov ax, [num1] ; AX = [num1]
xor dx, dx ; DX = 0
xor bx, bx ; BX = 0
mov bl, [num2] ; BL = [num2], BH = 0
div bx ; DX:AX / BX
mov [quotient], ax
mov [remainder], dx
(因为这也是一个BX
,你可能想要通过在顶部push bx
和最后一个pop bx
来保存其原始值。)
documentation for the DIV
instruction包含一个方便的表格,总结了8位,16位和32位分区的工作原理:
Operand Size | Dividend | Divisor | Quotient | Remainder | Maximum Quotient
--------------------------------------------------------------------------------------
Word/byte | AX | r/m8 | AL | AH | 2^8 - 1
Doubleword/word | DX:AX | r/m16 | AX | DX | 2^16 - 1
Quadword/doubleword | EDX:EAX | r/m32 | EAX | EDX | 2^32 - 1
“除数”是DIV
指令的唯一操作数。 “红利”是隐含的。请注意,“r / m”表示寄存器或内存操作数。