DIV instruction jumping to random location?

安稳与你 提交于 2019-12-13 15:17:45

问题


So I am having this exact problem.

The solution given is to zero out DX, but in my case it already is!
My program is to simply divide a 16 bit number by an 8 bit number.

My code is:

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

Any solution?


回答1:


You badly need to start using whitespace to separate your assembly code. This code is doing something extremely simple (dividing one number by another), yet it is extremely difficult to read. That should obviously not be the case: simple code should be simple to read! Why is it hard to read? Because you've got all of your boilerplate code jammed up against the code that's actually doing the division operation, and my eyes just glaze over. I'm not able to pick out the important bits from the boilerplate. Whitespace is free; don't be afraid of it. Your assembler doesn't mind.

Write it like this:

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

Now, isn't it substantially more clear what's what? Also, while MASM/TASM will let you get away with being sloppy, don't get into bad habits. That's another way to make your code unreadable and get the wrong results. There are two different ways that you can use symbols in your code: one way is to use the address/offset of that symbol, and the other way is to use the contents/value of that symbol. In MASM/TASM, when you want the address/offset, you need to use the OFFSET keyword. When you use the contents/value, you don't technically need to, but you really should wrap the symbol in brackets to indicate that it is being dereferenced. In other words, instead of:

mov ax, num1

write it:

mov  ax, [num1]

With that rant off my chest, let's look at what's wrong with your code. Michael Petch has already pointed out that this is another case where MASM/TASM's "do what I mean, not what I write" style is not doing you any favors. It is doing an 8-bit division because you've used an 8-bit operand (num2) with the DIV instruction. That means it's actually doing:

AX / [num2]

with the quotient in AL and the remainder in AH. If the quotient is larger than 8 bits, it won't fit in AL and the division will overflow.

The workaround is to do a 16-bit division, in which case the quotient will be placed in AX and the remainder will be placed in DX.

To get that, write the code thusly:

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

(Since this is also clobbering BX, you may want to save its original value by doing a push bx at the top and a pop bx at the end.)


The documentation for the DIV instruction contains a handy table summarizing how 8-bit, 16-bit, and 32-bit divisions work:

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

The "divisor" is the sole operand for the DIV instruction. The "dividend" is implicit. Note that "r/m" means either a register or memory operand.



来源:https://stackoverflow.com/questions/43522230/div-instruction-jumping-to-random-location

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!