Умножение путем многократного сложения в стек в nasm
У меня проблемы с результатом моей реализации. Если вы проследили это, это кажется правильным. Однако это дает неверный результат. Если вы введете 99 и 99, это даст 5318, но это должно дать 9801.
Между прочим, программа принимает два двузначных числа и умножает, многократно добавляя множитель (первый вход), пока не получит значение в множителе (второй вход)
Я попытался найти проблему, кажется, что когда я использую деление по размеру слова, это дает случайные значения. размер слова до 65656, но результат искажается, когда он превышает 255. Почему?
Просто обратите внимание на первый вариант, который заключается в умножении путем повторного сложения.
Небольшая помощь очень ценится.
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
1 ответ
Показанный ниже цикл неверен, поскольку он сбрасывает значение ax
в начале каждой итерации. Так что после выхода из цикла, ax
будет содержать первоначальное значение [ebp+10]
раз два, независимо от количества итераций.
while1:
mov ax, [ebp+10]
add ax, [ebp+10]
dec word [ebp+6]
cmp word [ebp+6], 1
jne while1
Хорошо, давайте посмотрим на ваш результат 5318. Предположительно, это в два раза больше [ebp+10]
; так [ebp+10]
имел бы значение 2659, что 0x0A63 в шестнадцатеричном. Это говорит мне о том, что старшие байты num1b
а также num2b
содержит символ перевода строки (код ASCII 0x0A).
Так что вам нужно исправить вашу петлю. Нечто подобное должно работать:
mov ax, 0
while1:
add ax, [ebp+10]
И вам также нужно очистить старший байт num1a..num2b
,