我正在尝试在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
它总是返回“ 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