组装幂(A,b)函数

Assembly Power(A,b) function

我正在尝试根据以下 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

谁能帮我找出我哪里出错了,或者更正我的代码,我们将不胜感激。

您正在存储一个字节,然后读回该字节 + 3 个垃圾字节。

%define z [ebp-4]    ; what's the point of this define if you write it out explicitly instead of  mov eax, z?
                     ; should just be a comment if you don't want use it

mov    byte[ebp-4], 1     ; leaves [ebp-3..ebp-1] unmodified
...
mov    eax, [ebp-4]       ; loads 4 bytes, including whatever garbage was there

使用调试器会告诉您此时 EAX 中出现了垃圾。您可以使用 movzx eax, byte [ebp-4] 或首先存储 4B 来修复它。

或者,更好的是,根本不使用任何额外的堆栈内存,因为在通常的 32 位调用约定中,您甚至可以在没有 saving/restoring 的情况下使用 ECX。将您的数据保存在寄存器中,这就是它们的用途。


您使用 [ebp+16] 的 "solution" 正在写入调用者拥有的堆栈 space。你只是很幸运,我猜它恰好将高 3 个字节归零,并且破坏它不会导致崩溃。


and    eax,1
test   eax,eax

是多余的:test eax, 1就足够了。 (或者如果你想销毁 eax,and eax, 1 根据结果设置标志)。

您的代码中还有大量其他低效率问题。