在nasm中未签名的除法

时间:2014-10-20 02:14:48

标签: assembly nasm integer-division

我一直在尝试调试一个小程序集程序,我要求分红和除数,并且必须输出商和余数。但是出于某种原因,我的商和余数不输出到屏幕。这是我的代码:

segment .data

prompt db "Please enter a number: ", 10
promptLen equ $-prompt
prompt2 db "Please enter the divisor: ", 10
prompt2Len equ $-prompt2
prompt3 db "Your quotient is: ", 10
prompt3Len equ $-prompt3
prompt4 db "Your remainder is: ", 10
prompt4Len equ $-prompt4

segment .bss

inputNum resb 2
inputDiv resb 2
quotient resb 2
remainder resb 2

segment .text

global _start

_start:

mov eax, 4
mov ebx, 1
mov ecx, prompt
mov edx, promptLen
int 80h

mov eax, 3
mov ebx, 0
mov ecx, inputNum
mov edx, 2
int 80h

mov eax, 4
mov ebx, 1
mov ecx, prompt2
mov edx, prompt2Len
int 80h

mov eax, 3
mov ebx, 0
mov ecx, inputDiv
mov edx, 2
int 80h

xor edx, edx
mov ax, [inputNum]
mov bx, [inputDiv]
sub ax, '0'
sub bx, '0'

div bx

add ax, '0'
add dx, '0'
mov [quotient], ax
mov [remainder], dx

mov eax, 4
mov ebx, 1
mov ecx, prompt3
mov edx, prompt3Len
int 80h

mov eax, 4
mov ebx, 1
mov ecx, [quotient]
mov edx, 2
int 80h

mov eax, 4
mov ebx, 1
mov ecx, prompt4
mov edx, prompt4Len
int 80h

mov eax, 4
mov ebx, 1
mov ecx, [remainder]
mov edx, 2
int 80h
jmp exit

exit:

mov eax, 1
xor ebx, ebx
int 80h

如果有人能帮我理解我做错了什么,我将不胜感激。

1 个答案:

答案 0 :(得分:0)

系统调用4(写入)在char *中需要ecx的缓冲区地址。使用您的代码:

mov eax, 4          ; sys_write
mov ebx, 1          ; standard output
mov ecx, [quotient] ; here, ecx <- your character code
mov edx, 2          ; two bytes (hmmm)
int 80h

您正在使用输入的实际数据加载ecx,而不是其地址。

您需要做的是加载ecx字符的地址,这可能只是:

mov ecx, quotient ; here, ecx <- your character address

您可能还希望将字节数减少到1而不是2。将整数转换为字符的方式(添加'0')仅适用于单字符数字,因此您只需要最低有效字节(x86最低内存地址的字节)。

其余的同上。


顺便说一句,当你修复它时,你仍然会得到一个有趣的结果。将5除以2会得到1的商和3的余数,显然是错误的。

这与您输入数据的方式有关,并将值加载到axbx

由于您正在为每个数字读取两个字节,因此内存将加载数字本身'5'0x35,后跟换行符{{ 1}}。

然后,当您将双字节加载到0x0a时,它会以ax结束。

从每个中减去0x0a350x0030)后,最终会得到'0'0x0a05,其中包含小数0x0a02和{{1} }}。当您划分这些数字时,确实会得到25652562的余数的商。

要解决此问题,您只需丢弃1,但在加载值时,可以更改:

3

成:

0x0a00