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
免责声明:我还没有测试过,但你应该明白了。
我正在尝试在 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
免责声明:我还没有测试过,但你应该明白了。