2017-11-11 120 views
0

我有下一个问题: 当我试图做一个较小的数字分成一个更大的一个我得到商很高,我不明白为什么。这里是我试图划分1到5的程序,结果是256.(也是变量'a'和'b'必须是db类型的) 有人可以帮助我吗?谢谢你在前进划分一个小数字不会给商0

.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

似乎是重复的所有这些“为什么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],这使得读取源,寻找漏洞要容易得多。

这样idiv按字节值5被执行。如果您要检查IDIV description,那么您应该能够识别出您正在使用ax/"r/m8"变体,因此结果将存储在al(商)和ah(其余部分)中。

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

mov bx, ax 

你猜怎么着是越来越 印刷 存入bx这里。 (打印是通过下一行使用那个丑陋的宏完成的,我个人更喜欢将该宏作为子程序移动到代码中,而不是像call那样......但它看起来像你刚刚开始用asm开始,所以目前专注于基础知识,将宏代码移动到子例程很简单,但如果您不了解asm,可能会出错)。

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

+0

非常感谢你,我了解正在发生的事情以及如何出现256,是的,你是对的,我是新手,我们刚刚开始在大学学习。 –

+0

要查找划分的规范复制目标,请查看[x86标记wiki](https://stackoverflow.com/tags/x86/info)并搜索“idiv”。这是我添加FAQ部分的原因之一。 (嗯,这不是一个确切的*重复的,因为这里的问题并没有意识到剩下的是AH,而不是没有清除上半部分的股息,但是Michael对链接dup的回答是8位操作数大小划分确实提到了它是如何工作的部分。不同的问题相同的答案。)无论如何,我不会建议删除这个答案,这很好。 –