简体   繁体   中英

Multiplication by repeated addition in stack in nasm

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.

while1:
  mov ax, [ebp+10]
  add ax, [ebp+10]

  dec word [ebp+6]
  cmp word [ebp+6], 1
  jne while1

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 of num1b and num2b contains a line-feed character (ASCII code 0x0A).

So you need to fix your loop. Something like this ought to work:

mov ax, 0
while1:
  add ax, [ebp+10]

And you also need clear the high byte of num1a..num2b .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM