x86-64递归乘法函数

问题描述 投票:0回答:1

我正在尝试在x86-64程序集中制作一个将两个数字x和y相乘并返回输出的函数,而不使用循环或mul运算符。这是我想出的代码,但我不知道为什么它总是只返回y。任何帮助表示赞赏。 edi中的x,esi中的y。

mul:
    xorl %eax, %eax
    testl %edi, %edi  #if x == 0 return 0 //base case 1
    je done1
    testl %esi, %esi  #if y == 0 return 0 //base case 1
    je done1

    cmpl $1, %edi   #if x == 1, return y //base case 2
    je done2

    addl %esi, %eax   #add eax by y (esi) x (edi) times
    decl %edi       #decrease x by 1 each run of the function. B stays the same
    call mul

done1:
    ret

done2:              #if x == 1, return y
    movl %esi, %eax
    ret
x86-64 multiplying
1个回答
0
投票

它总是返回“ y”,因为您将%edi减为

decl %edi

直到达到值“ 1”。然后执行以下指令序列:

call mul          # CALL -->
...
xorl %eax, %eax   # RESET accumulator value to 0
testl %edi, %edi  
je done1          # NOT TAKEN
testl %esi, %esi  
je done1          # NOT TAKEN
cmpl $1, %edi     # if x == 1, return y //base case 2
je done2          # HERE - THIS JUMP IS TAKEN
...
movl %esi, %eax   # MOVE y to return register %eax
ret               # It always returns y in %eax

要解决此问题,请先将xorl %eax, %eax行移到mul标签之前。然后删除行movl %esi, %eax以将%eax值保留为返回值。

所以这可能是一个解决方案(免责声明:我尚未测试):

    xorl %eax, %eax   # Set result value to "0"
    # check for 0 for "y" input 
    testl %esi, %esi  # if y == 0 return 0 //base case 1
    je done1          # immediately return on zero
mul:    
    test %edi, %edi   # if x == 0, exit recursive calls
    je done1
    addl %esi, %eax   # add eax by y (esi) x (edi) times
    decl %edi         # decrease x by 1 each run of the function. B stays the same
    call mul
    # PASS-THROUGH on stack unwinding
done1:
    ret
© www.soinside.com 2019 - 2024. All rights reserved.