x86-64 递归乘法函数

x86-64 recursive multiply function

我正在尝试在 x86-64 汇编中创建一个函数,该函数将两个数字 x 和 y 相乘,returns 不使用循环或 mul 运算符的输出。这是我想出的代码,但我不知道为什么它总是 returns y。任何帮助表示赞赏。 x 在 edi 中,y 在 esi 中。

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 , %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

它总是 returns "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 , %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 值保留为 return 值。

所以这可能是一个解决方案:

    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 y (esi) to eax 
    decl %edi         # decrease x by 1 each run of the function. B stays the same
    call mul
    # PASS-THROUGH on stack unwinding
done1:
    ret

免责声明:我还没有测试过,但你应该明白了。