I'm having problems with the result of my implementation. If you traced it, it seems to be right. However, it gives the wrong result. If you input 99 and 99 it gives 5318 but it should give 9801.
Btw, the program accepts two 2-digit numbers and multiplies by adding the multiplicand(first input) repeatedly until it satisfies the value in the multiplier(second input)
I have tried locating the problem, it seems that when i use word-size division it gives random values. word-size is upto 65,656 but the result corrupts when it exceeds 255. Why?
Just mind the first option which is the multiplication by repeated addition operation.
A little help is greatly appreciated.
section .data
msg db "Menu: "
msgLen equ $ -msg
msg2 db "[1]Multiplication by repeated addition"
msgLen2 equ $ -msg2
msg3 db "[2]Division by repeated subtraction"
msgLen3 equ $ -msg3
msg4 db "[3]Exit"
msgLen4 equ $ -msg4
msg5 db "Enter two numbers: "
msgLen5 equ $ -msg5
line db "", 10
result dw 0
ten dw 10
quo1 dw 0
quo2 dw 0
quo3 dw 0
rem1 dw 0
rem2 dw 0
rem3 dw 0
temp1 db 0
temp2 db 0
temp3 db 0
section .bss
choice resb 1
num1a resw 1
num1b resw 1
num2a resw 1
num2b resw 1
section .text
global _start
_start:
do_while:
mov eax, 4
mov ebx, 1
mov ecx, msg
mov edx, msgLen
int 80h
mov eax, 4
mov ebx, 1
mov ecx, line
mov edx, 1
int 80h
mov eax, 4
mov ebx, 1
mov ecx, msg2
mov edx, msgLen2
int 80h
mov eax, 4
mov ebx, 1
mov ecx, line
mov edx, 1
int 80h
mov eax, 4
mov ebx, 1
mov ecx, msg3
mov edx, msgLen3
int 80h
mov eax, 4
mov ebx, 1
mov ecx, line
mov edx, 1
int 80h
mov eax, 4
mov ebx, 1
mov ecx, msg4
mov edx, msgLen4
int 80h
mov eax, 4
mov ebx, 1
mov ecx, line
mov edx, 1
int 80h
mov eax, 3
mov ebx, 0
mov ecx, choice
mov edx, 2
int 80h
sub byte [choice], 30h
cmp byte [choice], 1
je menu1
;cmp byte [choice], 2
;je menu2
cmp byte [choice], 3
je exit
jg do_while
jl do_while
menu1:
mov eax, 4
mov ebx, 1
mov ecx, msg5
mov edx, msgLen5
int 80h
mov eax, 3
mov ebx, 0
mov ecx, num1a
mov edx, 1
int 80h
mov eax, 3
mov ebx, 0
mov ecx, num1b
mov edx, 2
int 80h
mov eax, 3
mov ebx, 0
mov ecx, num2a
mov edx, 1
int 80h
mov eax, 3
mov ebx, 0
mov ecx, num2b
mov edx, 2
int 80h
sub word [num1a], 30h ;conversion
sub word [num1b], 30h
sub word [num2a], 30h
sub word [num2b], 30h
push result
push word [num1a]
push word [num1b]
push word [num2a]
push word [num2b]
call func1
mov ax, [result] ;9801
mov dx, 0
mov bx, 10
div bx
mov word [quo1], ax ;980
mov word [rem1], dx ;1
mov ax, [quo1]
mov dx, 0
mov bx, 10
div bx
mov word [quo2], ax ;98
mov word [rem2], dx ;0
mov ax, [quo2]
mov dx, 0
mov bx, 10
div bx
mov word [quo3], ax ;9
mov word [rem3], dx ;8
add word [quo3], 30h
add word [rem3], 30h
add word [rem2], 30h
add word [rem1], 30h
mov eax, 4
mov ebx, 1
mov ecx, quo3
mov edx, 1
int 80h
mov eax, 4
mov ebx, 1
mov ecx, rem3
mov edx, 1
int 80h
mov eax, 4
mov ebx, 1
mov ecx, rem2
mov edx, 1
int 80h
mov eax, 4
mov ebx, 1
mov ecx, rem1
mov edx, 1
int 80h
mov eax, 4
mov ebx, 1
mov ecx, line
mov edx, 1
int 80h
jmp do_while
func1:
mov ebp, esp
mov ax, [ebp+10] ;90
mov dx, 0
mul word [ten]
mov [ebp+10], ax
mov ax, [ebp+8] ;9
add word [ebp+10], ax ;99 on [ebp+10]
mov ax, [ebp+6] ;90
mov dx, 0
mul word [ten]
mov [ebp+6], ax
mov ax, [ebp+4] ;9
add word [ebp+6], ax ;99 on [ebp+6]
while1:
mov ax, [ebp+10]
add ax, [ebp+10]
dec word [ebp+6]
cmp word [ebp+6], 1
jne while1
end1:
mov ebx, [ebp+12]
mov [ebx], ax
ret 12
exit:
mov eax, 1
mov ebx, 0
int 80h
Your loop shown below is incorrect, because it resets the value of
ax
at the beginning of each iteration. So upon exiting the loop,ax
will contain the original value of[ebp+10]
times two, regardless of the number of iterations.Ok, let's look at your result of 5318. Supposedly, that's twice the value of
[ebp+10]
; so[ebp+10]
would've had the value 2659, which is 0x0A63 in hexadecimal. This suggests to me that the high bytes ofnum1b
andnum2b
contains a line-feed character (ASCII code 0x0A).So you need to fix your loop. Something like this ought to work:
And you also need clear the high byte of
num1a..num2b
.