Assembly x86汇编-使用加法查找幂

Assembly x86汇编-使用加法查找幂,assembly,x86,masm,irvine32,exponentiation,Assembly,X86,Masm,Irvine32,Exponentiation,程序将接受用户提供的两个数字,并显示这两个数字的和、积和幂(a^b)。 然而,这里有一个陷阱 该计划必须: 使用AddNumbers函数 在MultiplyNumbers函数中使用AddNumbers函数 在CalculatePower函数中使用MultiplyNumbers函数 我不知道如何通过加法函数实现乘法来求两个数的乘积。我无法理解其背后的逻辑。我显然做错了什么,但我不知道是什么。(请忽略代码的低效性,我只想知道我在寻找两者的乘积时做错了什么) 我的代码到目前为止 INCLUDE Irv

程序将接受用户提供的两个数字,并显示这两个数字的和、积和幂(a^b)。 然而,这里有一个陷阱

该计划必须: 使用AddNumbers函数 在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

试试这个。您的代码分析起来很复杂,因为您在不同的过程中有不同的循环,而无需再次初始化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

这个容易多了相信我。我只是不知道它是怎么工作的呵呵

 %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

你肯定在学校里学过乘法和加法的关系。引用维基百科的话:“两个整数的乘法等于其中一个整数与另一个整数相加的次数;例如,3乘以4(通常称为“3乘以4”)可以通过将4的3个副本相加来计算。”.乘法不能简单地在x86上使用
mul/imul
指令,这似乎很疯狂。。。无论如何,你可以模仿它。你在理解上的许多困难是由于缺乏评论造成的。如果你在写的每行代码上都加上一条(有意义的、准确的)注释,那么每行代码上的注释就会亮很多?在国际海事组织,只有当准则难以遵循或做了一些非标准的事情时,才有必要发表评论。这些评论是有用的。在每一行上加上注释会大大降低信噪比,依我看。汇编代码已经很难理解了,取消mul指令的使用是相当不标准的。很明显,这是为了教育目的,而不是为了生产。所以对于这种情况,我想说应该有更多的注释而不是代码。这个例子是可以的,但是问题陈述特别提到AddNumbers函数是由乘法和幂函数调用的。我会让函数在eax中返回结果。由于输入只需要两个值,因此esi和edi可以用作寄存器输入。微软的fastcall模型使用ecx和edx,但由于ecx可以用于循环,使用esi和edi将意味着更少的注册复制。伙计们,谢谢你们的评论,我将在我继续我的课程时带上它们。另外,f6a4,非常感谢您提供的解决方案。这并不完全是我需要如何完成程序,但它给了我一个解决方案,帮助我找出我做错了什么,以及下次要寻找什么,谢谢!PS-我注意到“xor”是程序中非常重要的一部分,删除它会降低产品功能。我不太清楚这到底是为什么(这仍然是一个谜)。有什么解释吗?@rcgldr:你说得对,我添加了一个版本,从mulitapplication和power proc调用sum proc。是的,使用更多的寄存器和更少的内存寻址会更好(我也会添加一个宏),但这是为了学习,代码应该对初学者来说是可以理解的(希望如此)。