【发布时间】:2016-10-18 17:56:33
【问题描述】:
我正在尝试基于此 c 代码制作一个汇编 power(a, b) 函数:
int power(int x, int y)
{
int z;
z = 1;
while (y > 0) {
if ((y % 2) == 1) {
y = y - 1;
z = z * x;
} else {
y = y / 2;
x = x * x;
}
}
return z;
}
虽然,由于某种原因,它只能得到一些正确的输出,我无法弄清楚问题出在哪里。这是我的汇编代码:
;* int power(int x, int y); *
;*****************************************************************************
%define y [ebp+12]
%define x [ebp+8]
%define z [ebp-4]
power:
push ebp
mov ebp,esp
sub esp,16
mov byte[ebp-4], 1
jmp L3;
L1:
mov eax,[ebp+12]
and eax,0x1
test eax,eax
je L2;
sub byte[ebp+12],1
mov eax,[ebp-4]
imul eax, [ebp+8]
mov [ebp-4],eax
jmp L3;
L2:
mov eax,[ebp+12]
mov edx,eax
shr edx,31
add eax,edx
sar eax,1
mov [ebp+12],eax
mov eax,[ebp+8]
imul eax,[ebp+8]
mov [ebp+8],eax
L3:
cmp byte[ebp+12],0
jg L1;
mov eax,[ebp-4]
leave
ret
当我运行它时,这是我的输出:
power(2, 0) returned -1217218303 - incorrect, should return 1
power(2, 1) returned 2 - correct
power(2, 2) returned -575029244 - incorrect, should return 4
power(2, 3) returned 8 - correct
谁能帮我找出我哪里出错了,或者纠正我的代码,任何帮助将不胜感激。
【问题讨论】:
-
学习使用调试器并注释您的代码,尤其是在您希望其他人提供帮助时。
-
您是否意识到
if ((y % 2) == 1)重写为if ((y & 1) != 0)时更容易在汇编程序中编码?不需要比较,只需要一个测试和一个分支。 -
@WeatherVane 大多数编译器应该足够聪明,可以通过适当的移位/掩码替换除法/模数的 2 次幂。
-
@dbush 是一个这么聪明的汇编程序吗?我的意思是这样写会更容易翻译。
-
我可以看到减量现在在做什么。它导致循环的下一次迭代转到
else部分,因此除法/平方被延迟到下一次迭代。不过,这似乎是一个杂项,因为这意味着对每个设置位的条件进行额外的评估。