【问题标题】:Multiplication by repeated addition in stack in nasmnasm中堆栈中重复加法的乘法
【发布时间】:2013-08-13 11:01:25
【问题描述】:

我的实施结果有问题。如果你追踪它,它似乎是正确的。 但是,它给出了错误的结果。 如果你输入 99 和 99,它会给出 5318,但它应该给出 9801。

顺便说一句,程序接受两个 2 位数字并通过重复添加被乘数(第一个输入)来相乘,直到它满足乘数(第二个输入)中的值

我已尝试定位问题,似乎当我使用字长除法时,它会给出随机值。 word-size 最大为 65,656,但超过 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

【问题讨论】:

  • 你确定你的numXY变量的高字节是0吗?
  • 什么numXY?对不起,你能澄清一下。
  • 是的,我很确定。它接受输入。当我打印 num1a、num1b、num2a、num2b 时,它打印了 9。

标签: assembly stack nasm word-size


【解决方案1】:

下面显示的循环不正确,因为它会在每次迭代开始时重置ax 的值。因此,在退出循环时,ax 将包含 [ebp+10] 的原始值乘以 2,无论迭代次数如何。

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。这表明num1bnum2b 的高字节包含换行符(ASCII 代码0x0A)。

所以你需要修复你的循环。像这样的东西应该可以工作:

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

你还需要清除num1a..num2b的高字节。

【讨论】:

  • num1a, num1b, num2a, num2b 在我打印它们时为 9。我还打印了 [ebp+10] 和 [ebp+6],它们都给出了 99。我自己添加了一次 [ebp+10],它使用字节大小除法产生了 198,但字大小没有。我很困惑。
  • 高字节是什么意思?
  • 一个字有 16 位。高字节 I 表示位 8..15。
  • "num1a, num1b, num2a, num2b 在我打印它们时是 9。" 你打印的是整个单词,还是只打印低字节?
  • 我打印了整个内容:添加 word [num1a], 30h 然后 mov ecx, num1a,就像在打印中一样。
猜你喜欢
  • 1970-01-01
  • 2017-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多