2014-09-15 6 views
-1

Программа будет принимать два номера от пользователя и отображать сумму, произведение и мощность (a^b) этих двух чисел. Вот улов, однако ...x86 Сборка с помощью добавления

Программа ДОЛЖНА: использовать AddNumbers функционировать Используйте эту функцию AddNumbers через MultiplyNumbers функционировать использование этой функции MultiplyNumbers в функции CalculatePower

Я не могу понять, как найти Продукт двух чисел путем реализации функции умножения через сложение. Я не могу понять логику этого. Я, очевидно, что-то делаю неправильно, но я не уверен, что. (Просьба игнорировать неэффективность кода, я просто хочу знать, что я делаю неправильно, насколько найти продукт двух)

Мой код до сих пор ..

INCLUDE Irvine32.inc 
.data 
str1 BYTE "Enter a positive integer: ",0 
str2 BYTE "The sum is: ",0 
str3 BYTE "The product is: ",0 
str4 BYTE "The power result is: ",0 

.code 
main PROC 

call GetInteger 
call Crlf 
mov eax, ebx 
call AddNumbers 

mov edx, OFFSET str2 
call WriteString 
call WriteInt 
call Crlf 
mov eax, 0 
mov ecx, edi 
call MultiplyNumber 
mov eax, edx 
mov edx, OFFSET str3 
call WriteString 
call WriteInt 
call Crlf 
call CalculatePower 
mov eax, esi 
mov edx, OFFSET str4 
call WriteString 
call WriteInt 
call Crlf 

exit 
main ENDP 

GetInteger PROC 
mov edx, OFFSET str1 
call WriteString 
call ReadInt 
mov ebx, eax 
call WriteString 
call ReadInt 
mov edi, eax 
ret 
GetInteger ENDP 

CalculatePower PROC USES edi ebx 

mov ecx, edi 
mov esi, 0 
L2: 

    call MultiplyNumber 
    add esi, edx 
    loop L2 
    ret 
CalculatePower ENDP 

MultiplyNumber PROC USES ebx edi ecx 

mov edx, 0 
L1: 
    mov edi, ebx 
    mov eax, 0 
    call AddNumbers 
    add edx, eax 
    loop L1 
    ret 
MultiplyNumber ENDP 

AddNumbers PROC 

    add eax, edi 

ret 
AddNumbers ENDP 

END main 
+3

Несомненно, вы узнали в школе, как умножение относится к сложениям (?). Процитировать из википедии: _ «Умножение двух целых чисел эквивалентно добавлению одного из них с собой столько же раз, сколько значение другого, например, 3 умноженное на 4 (часто упоминаемое как« 3 раза 4 ") можно рассчитать, добавив 3 копии из 4 вместе" _. – Michael

+1

Кажется безумным, что умножение не может просто использовать инструкции 'mul/imul' на x86 ... в любом случае вы можете использовать [shift-add] (http://stackoverflow.com/questions/2776211/how-can-i -multiply-and-divide-using-only-bit-shifting-and-added) имитировать его. –

+0

Большая часть ваших трудностей в понимании обусловлена ​​отсутствием комментариев. Если вы поместите (значимый, точный) комментарий по каждой строке кода, который вы пишете, свет будет намного быстрее –

ответ

0

Попробуйте это , Ваш код сложно анализировать, потому что у вас есть разные циклы в различных процедурах без ECX снова инициализируется и т.д.

OPTION CASEMAP:NONE 

INCLUDE Irvine32.inc 

ExitProcess proto, dwExitCode:dword 

.data 
    str1 BYTE "Enter a positive integer: ",0 
    str2 BYTE "The sum is: ",0 
    str3 BYTE "The product is: ",0 
    str4 BYTE "The power result is: ",0 
    num1 DWORD 0 
    num2 DWORD 0 
    sum DWORD 0 
    prod DWORD 0 
    pow DWORD 0 
    tmp DWORD 0 

.code 
    main PROC 

     mov edx, OFFSET str1 ;// Input 
     call WriteString 
     call ReadInt 
     mov [num1], eax 
     mov edx, OFFSET str1 
     call WriteString 
     call ReadInt 
     mov [num2], eax 

     call doSum    ;// Calculations 
     call doMul 
     call doPow 

     mov edx, OFFSET str2 ;// Output 
     call WriteString 
     mov eax, [sum] 
     call WriteInt 
     call Crlf 

     mov edx, OFFSET str3 
     call WriteString 
     mov eax, [prod] 
     call WriteInt 
     call Crlf 

     mov edx, OFFSET str4 
     call WriteString 
     mov eax, [pow] 
     call WriteInt 
     call Crlf 

     invoke ExitProcess, 0 

    main ENDP 

    doSum PROC    ;// Sum 
     mov eax, [num1] 
     add eax, [num2] 
     mov [sum], eax 
     ret 
    doSum ENDP 

    doMul PROC    ;// Multiply: Add num1 x num2 times 
     xor eax, eax 
     mov ecx, [num2] 
     ADD_LOOP: 
      add eax, [num1] 
     loop ADD_LOOP 
     mov [prod], eax 
     ret 
    doMul ENDP 

    doPow PROC    ;// Power: Add num1 x num2 times and 
     mov eax, [num1]  ;// add result x num2 times till ebx=0 
     mov [tmp], eax 
     mov ebx, [num2] 
     dec ebx 
     POW_LOOP: 
      xor eax, eax 
      mov ecx, [num1] 
      ADDPOW_LOOP: 
       add eax, [tmp] 
      loop ADDPOW_LOOP 
      mov [tmp], eax 
      dec ebx 
     jnz POW_LOOP 
     mov [pow], eax 
     ret 

    doPow ENDP 

END main 

Модифицированная версия с вызовом сложения прок от умножения и мощности прок:

OPTION CASEMAP:NONE 

INCLUDE Irvine32.inc 

ExitProcess proto, dwExitCode:dword 

.data 
    str1 BYTE "Enter a positive integer: ",0 
    str2 BYTE "The sum is: ",0 
    str3 BYTE "The product is: ",0 
    str4 BYTE "The power result is: ",0 
    num1 DWORD 0 
    num2 DWORD 0 
    sum DWORD 0 
    prod DWORD 0 
    pow DWORD 0 
    tmp DWORD 0 

.code 
    main PROC 

     mov edx, OFFSET str1 ;// Input 
     call WriteString 
     call ReadInt 
     mov [num1], eax 
     mov edx, OFFSET str1 
     call WriteString 
     call ReadInt 
     mov [num2], eax 

     mov eax, [num1]   ;// Calculations 
     mov ebx, [num2] 
     mov ecx, 1 
     call doSum   
     mov [sum], eax 
     call doMul 
     call doPow 

     mov edx, OFFSET str2 ;// Output 
     call WriteString 
     mov eax, [sum] 
     call WriteInt 
     call Crlf 

     mov edx, OFFSET str3 
     call WriteString 
     mov eax, [prod] 
     call WriteInt 
     call Crlf 

     mov edx, OFFSET str4 
     call WriteString 
     mov eax, [pow] 
     call WriteInt 
     call Crlf 

     invoke ExitProcess, 0 

    main ENDP 

    doSum PROC    ;// Sum: (add ebx to eax) * ecx times 
     SUM_LOOP:   ;// when ecx = 1 => simple addition a+b 
     add eax, ebx 
     loop SUM_LOOP 
     ret 
    doSum ENDP 

    doMul PROC    ;// Multiply: Add num1 x num2 times 
     xor eax, eax 
     mov ebx, [num1] 
     mov ecx, [num2] 
     call doSum   ;// call Sum proc 
     mov [prod], eax 
     ret 
    doMul ENDP 

    doPow PROC    ;// Power: Add num1 x num2 times and 
     mov eax, [num1]  ;// add result x num2 times till end 
     mov [tmp], eax 
     mov esi, [num2] 
     dec esi 
     POW_LOOP: 
      xor eax, eax 
      mov ebx, [tmp] 
      mov ecx, [num1] 
      call doSum  ;// Call Sum proc 
      mov [tmp], eax 
      dec esi 
     jnz POW_LOOP 
     mov [pow], eax 
     ret 

    doPow ENDP 

END main 
+0

Этот пример в порядке, но в заявлении о проблеме конкретно упоминается, что функция AddNumbers должна вызываться функциями умножения и мощности. Я бы просто вернуть функции в eax. Поскольку для ввода требуется только два значения, esi и edi могут использоваться в качестве входных регистров. Модель fastcall от Microsoft использует ecx и edx, но поскольку ecx можно использовать для циклирования, использование esi и edi будет означать меньшее копирование регистра. – rcgldr

+0

Ребята, спасибо за ваши комментарии, и я отведу их со мной, когда я продвигаюсь вперед в своем курсе. Кроме того, f6a4, большое вам спасибо за это решение. Это было не совсем так, как мне нужна была программа, но она дала мне решение для работы и помогла мне разобраться, что я делаю неправильно, и что искать в следующий раз, спасибо! PS-Я заметил, что «xor» - очень важная часть программы, и удаление ее уменьшает функцию продукта. Я не совсем уверен, почему это так (по-прежнему это noob). Любое объяснение? – Bubz21

+0

@rcgldr: Вы правы, я добавил версию, которая вызывает сумму proc от mulitplication и power proc.И да, было бы лучше использовать больше регистров и меньше адресации памяти (я бы добавил и макрос), но это для учебных целей, и код должен быть понятным для новичка (надеюсь). – f6a4

0

Это один является мне гораздо легче доверять. Я просто не знаю, как это работает.

%include "asm_io.inc" 
segment .data 
    prompt db "Enter first num ",0 
    prompt1 db "Enter second num ",0 
    prompt2 db "Equals ",0 
segment .bss 
    input1 resd 1 
    input2 resd 1 
segment .text 
    global _asm_main 
_asm_main: 
    enter 0,0 
    pusha 

    mov eax, prompt 
    call print_string 

    call read_int 
    mov [input1], eax 

    mov eax, prompt1 
    call print_string 

    call read_int 
    mov [input2], eax 

    mov eax, prompt2 
    call print_string 

    mov eax, [input1] 
    mov ebx, [input2] 
    mov ebx, eax 
    mul ebx 
    call print_int 

popa 
mov eax,0 
mov ebx,0 
leave 
ret 
Смежные вопросы