将较小的数字除以较大的数字不会给出商数0

时间:2017-11-11 09:30:21

标签: assembly tasm

我有下一个问题: 当我尝试将较小的数字除以较大的数字时,我得到的商数非常高,我无法理解为什么。这是我试图将1除以5并且结果为256的程序。(变量'a'和'b'也必须是db类型) 有人能帮我吗?提前谢谢

.model small 
afisareanr macro nr
local m11
local m
xor ax, ax
mov ax, nr
push ax             
mov si, 10          
mov di, 5           

mov dx, 0           
cmp ax, 0           
jge m               
neg ax              

m:div si            
add dl, 30h         

mov s[di],dl        

xor dx,dx           
dec di              
cmp ax, 0           

jne m               

pop ax              

cmp ax, 0           
jge m11             
mov s[di], '-'      

m11: 
mov ah, 9           
lea dx, s
int 21h
endm

.stack 
.data 
a db 5
b db 1
s    db 6 dup(" "), '$'

.code 
mov ax, @data 
mov ds, ax

xor ax, ax
xor bx, bx
mov al, b
idiv a
mov bx, ax
afisareanr bx

mov ax, 4c00h
int 21h

end

1 个答案:

答案 0 :(得分:1)

似乎是所有这些"为什么DIV不起作用的副本"问题,但有点具体和回答它比我寻找好的欺骗更容易(如果其他人标记一个好的话,将删除答案)。

mov al, b     ; AL = b (1) .. and i prefer squared bracket Intel style
              ; like mov al,[b]  - to see easily memory is accessed
idiv a

现在这个编译没有错误只是因为你在MASM怪癖模式中使用TASM,在TASM"理想"模式这将是语法错误IIRC(确实在~1994-1999使用TASM,所以我可能记得它错了)。

问题是,它不清楚,数据大小是什么..在装配经验丰富的程序员喜欢源非常精确和清晰的意图,即idiv byte ptr [a],这使得阅读源和寻找bug更容易。

执行idiv字节值5。如果您要检查IDIV description,则应该能够识别出您使用的是ax / "r/m8"变体,因此结果存储在al(商)和ah中(余数) )。

1/5 = 0,余数1 ......所以al = 0, ah = 1。但这意味着,ax整个16位寄存器现在包含值0100h = 256

mov bx, ax

猜猜在此bx存储了打印的内容。 (打印是使用那个丑陋的宏通过下一行完成的,我个人更喜欢将该宏移动到代码中作为子例程,而不是call ......但是看起来你刚开始使用asm,所以暂时专注于基础,将宏代码移动到子程序很简单,但如果你对asm一无所知可能会出错。

顺便说一下,如果你安装了TASM,你也有TD(Turbo Debugger)。用它来看看自己,每条指令后CPU中发生了什么。它使学习ASM变得更加容易。