2014-09-15 2 views
-1

이 프로그램은 사용자로부터 두 개의 숫자를 받고 두 숫자의 합, 곱 및 지수 (a^b)를 표시합니다. 가 AddNumbers이x86 조립 - 추가를 사용하여 힘을 얻으십시오

내가 방법을 알아낼 수없는 MultiplyNumbers에서 AddNumbers 함수는 CalculatePower 기능에 사용 MultiplyNumbers 기능을 작동 사용 기능을 사용하여 여기에 는

이 프로그램은해야 ... 그러나, 캐치입니다 덧셈 함수를 통해 곱셈을 구현함으로써 두 수의 곱을 찾을 수 있습니다. 나는 그 뒤에있는 논리를 이해할 수 없다. 나는 틀린 일을 분명히하고있다. 그러나 나는 무엇이 확실하지 않다.

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 ")는 4의 3 개의 사본을 추가하여 계산할 수 있습니다"_. – Michael

+1

곱셈이 단순히 x86에서 mul/imul 명령을 사용할 수 없다는 것이 제정신이 아닌 것처럼 보입니다. 어쨌든 [shift-add] (http://stackoverflow.com/questions/2776211/how-can-i)를 사용할 수 있습니다. 곱셈 및 나눗셈을 사용하는 비트 시프 팅 및 가산)은 그것을 에뮬레이션한다. –

+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 
곱셈과 전력 PROC에서 추가 시저의 호출로

수정 된 버전 :

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를 레지스터 입력으로 사용할 수 있습니다. Microsoft의 fastcall 모델은 ecx 및 edx를 사용하지만 ecx는 반복에 사용할 수 있으므로 esi 및 edi를 사용하면 등록 복사가 줄어 듭니다. – rcgldr

+0

여러분, 의견을 보내 주셔서 감사 드리며 제가 앞으로 나아갈 때 저와 함께 데려가겠습니다. 또한, f6a4, 정말 고맙습니다. 정확히 어떻게 프로그램을 완성해야하는지는 정확히 알 수는 없었지만, 해결 방법을 제시해 주었고, 내가 뭘 잘못하고 다음에 무엇을 찾을 지 알아 냈습니다. 고마워요! PS- 나는 'xor'가 프로그램의 매우 중요한 부분 인 것을 알아 차 렸습니다. 제거하면 제품 기능이 줄어 듭니다. 나는 이것이 왜 (왜 아직도이 멍청한 놈인지) 확실하지 않다. 설명이 뭐야? – Bubz21

+0

@rcgldr : 맞습니다. mulitplication 및 power proc에서 sum proc을 호출하는 버전을 추가했습니다.그리고 네, 더 많은 레지스터와 더 적은 메모리 어드레싱 (매크로도 추가 할 것입니다)을 사용하는 것이 좋겠지 만, 이것은 학습 목적을위한 것이며 코드는 초보자를 위해 이해할 수 있어야합니다 (바라건대). – f6a4

0

이 하나입니다 훨씬 쉽게 나를 신뢰해라. 나는 그것이 어떻게 hehehe를 작동하는지 모른다.

%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