DIV指令跳转到随机位置?

2024-01-17

所以我有这个确切的问题 https://stackoverflow.com/questions/8236636/8086-assembly-div-going-ape-ip-jumping-to-a-weird-location-endlessly#_=_.

给出的解决方案是归零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

有什么解决办法吗?


您迫切需要开始使用空格来分隔汇编代码。这段代码正在做一些事情极其简单(一个数字除以另一个数字),但它是极其很难阅读。显然情况并非如此:简单的代码应该易于阅读!为什么读书难?因为你所有的样板代码都与实际执行除法运算的代码相冲突,而我的眼睛却呆滞了。我无法从样板中找出重要的部分。空白是免费的;不要害怕它。你的汇编器不介意。

像这样写:

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 可以让你避免马虎,但不要养成坏习惯。这是另一种使代码不可读并得到错误结果的方法。在代码中使用符号有两种不同的方法:一种方法是使用address/offset该符号的另一种方法是使用contents/value那个符号的。在MASM/TASM中,当需要地址/偏移量时,需要使用OFFSET关键词。当您使用内容/值时,从技术上讲您不需要这样做,但您确实should将符号括在方括号中以指示它正在被取消引用。换句话说,而不是:

mov ax, num1

写下来:

mov  ax, [num1]

说了这么多,让我们看看你的代码出了什么问题。 Michael Petch 已经指出,这是 MASM/TASM 的“做我的意思,而不是我写的”风格的另一个例子,这对你没有任何好处。它正在执行 8 位除法,因为您使用了 8 位操作数 (num2)与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在最后。)


The 的文档DIV操作说明 http://x86.renejeschke.de/html/file_module_x86_id_72.html包含一个方便的表格,总结了 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”表示寄存器或内存操作数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

DIV指令跳转到随机位置? 的相关文章

随机推荐