Умножение с использованием сдвигов в сборке. Но получается слишком большое число! Где я ошибаюсь?

У меня возникают проблемы с использованием сдвигов для умножения двух чисел, заданных пользователем. Он просит пользователя ввести два целых числа и предполагается их умножить. Моя программа хорошо работает, запрашивая целые числа, но когда она дает произведение, это астрономическое число, которое далеко не верно. Где я ошибаюсь? какой регистр читает?

%include "asm_io.inc"
segment .data

message1 db "Enter a number: ", 0 message2 db "Enter another number: ", 0 message3 db "The product of these two numbers is: ", 0

segment .bss

input1 resd 1 input2 resd 1

segment .text Global main main: enter 0,0 pusha

mov     eax, message1   ; print out first message
call    print_string
call    read_int    ; input first number
mov     eax, [input1]


mov     eax, message2   ; print out second message
call    print_string
call    read_int    ; input second number
mov ebx, [input2]

cmp     eax, 0      ; compares eax to zero
cmp ebx, 0      ; compares ebx to zero
jnz LOOP        ; 

LOOP:
shl eax, 1

dump_regs 1 mov eax, message3 ; print out product call print_string mov ebx, eax call print_int


person BDilly    schedule 19.03.2011    source источник
comment
пожалуйста, отформатируйте код более разборчиво. на первый взгляд, я не вижу там ничего похожего на умножение (там один сдвиг на 1, а не в цикле), я даже не вижу нигде, что вы на самом деле действуете на входных значениях, кроме проверки ebx на ноль.   -  person Mat    schedule 20.03.2011
comment
Ваш код не имеет особого смысла и, похоже, не содержит ничего похожего даже на попытку умножения. Возможно, при вырезании/вставке была допущена ошибка?   -  person Jerry Coffin    schedule 20.03.2011
comment
выравнивание непоследовательно, слишком большой интервал по вертикали, и вы понятия не имеете, что делает ваш включенный файл/как реализованы функции print_* и read_*.   -  person Mat    schedule 20.03.2011


Ответы (2)


Вы ошибаетесь почти во всем, кроме того, что просите цифры.

  • Вы действуете так, как будто read_int записывает прочитанное целое число в input1 при первом вызове и в intput2 во второй раз. Это почти наверняка не так.
  • Даже в этом случае вы загружаете первое число в eax, а затем сразу перезаписываете его адресом message2.
  • Даже если eax и ebx были правильно загружены с входными значениями, ваш код, который должен умножать два, на самом деле делает что-то вроде «если второе число не равно нулю, умножьте eax на 2. В противном случае оставьте его. один."
  • Даже если бы цикл был организован правильно, он бы умножал eax на 2 в степени ebx.
  • Затем вы все равно перезаписываете этот результат адресом message3, так что все это не имеет значения.
  • В конце концов, из этого кода невозможно определить, какой регистр печатается. Между этим вопросом и вашим другим вопросом вы, кажется, ожидая, что print_int напечатает любой из eax, ebx или ecx.
person Anomie    schedule 19.03.2011

Игнорируя код, который вы опубликовали, и строго глядя на то, как умножать числа (без использования инструкции умножения), вы делаете что-то вроде этого:

mult proc
; multiplies eax by ebx and places result in edx:ecx
    xor ecx, ecx
    xor edx, edx
mul1:
    test ebx, 1
    jz  mul2
    add ecx, eax
    adc edx, 0
mul2:
    shr ebx, 1
    shl eax, 1
    test ebx, ebx
    jnz  mul1
done:
    ret
mult endp
person Jerry Coffin    schedule 19.03.2011