2014-10-20 2 views
0

Я пытался отладить небольшую программу сборки, где я прошу дивиденд и делитель, и мне нужно вывести частное и остальное. Однако по какой-то причине мой коэффициент и остаток не выводятся на экран. Вот мой код:Unsigned division in nasm

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 

Я был бы признателен, если бы кто-то мог помочь мне понять, что я делаю неправильно.

+0

Какие данные вы ввода? – paxdiablo

+0

@paxdiablo, я проверил его с моим дивидендом, равным 5, а делитель был 2 –

+0

@paxdiablo, Это сработало! Спасибо! Однако, используя одни и те же данные, я получаю 1 в качестве частного и 3 в качестве остатка. Любая идея почему? –

ответ

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 

Вы также можете уменьшить количество байтов в один, а не два. То, как вы превращаете целые числа в символы (добавление '0'), будет работать только для чисел с одним символом, так что вам нужен только младший старший байт (тот, который имеет наименьший адрес памяти для x86).

Ditto для остатка.


Как и в сторону, когда вы сделать исправить это, вы все равно получите забавный результат. Разделение 5 на 2 дает вам коэффициент 1 и остаток 3, явно неправильный.

Это связано с тем, как вы вводите данные и загружаете значения в ax и bx.

Поскольку вы читаете два байта для каждого номера, память загружается с самой цифрой '5' или 0x35, с последующим символом новой строки 0x0a.

Затем, когда вы загрузите два-байтовый слово в ax, он заканчивает с 0x0a35.

После вычитания 0x0030 ('0') от каждого, вы в конечном итоге с 0x0a05 и 0x0a02, который, в десятичной системе, 2565 и 2562. Когда вы разделите номерами, вы действительно получите коэффициент 1 и остаток от 3.

Чтобы исправить это, вы можете просто выбросить 0x0a00, но при загрузке значения, путем изменения:

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

в:

xor edx, edx 
mov ax, [inputNum] 
mov bx, [inputDiv] 
and ax, 0xff   ; add these 
and bx, 0xff   ; two lines. 
sub ax, '0' 
sub bx, '0' 
+0

Это сработало! Спасибо! Однако, используя одни и те же данные, я получаю 1 в качестве частного и 3 в качестве остатка. Любая идея почему? –

+0

Любое предложение о том, как сделать десятичное преобразование, чтобы я не ограничивался только одним номером символа? –

+0

@ user116317, я обновил ответ о том, почему вы получаете странный результат. Что касается того, как обрабатывать более одной цифры, вероятно, это должен быть другой вопрос о SO. Вы получите больше ответа таким образом, а не спрашиваете в поле комментариев. – paxdiablo