汇编intel x86哪些地址可用于定义参数

时间:2016-10-19 22:22:28

标签: c assembly nasm

我可以使用哪些记忆点? 我有这个汇编代码通过递归来驱动(a,b):

 int power(int x, int y);                                                  *
;*****************************************************************************
%define x [ebp+8]
%define y [ebp+12]
power:
    push ebp    
    mov ebp, esp

    mov eax, y  ;move y into eax
    cmp eax, 0  ;compare y to 0
    jne l10;    ;if not equal, jump to l10  
    mov eax, 1  ;move 1 into eax
    jmp l20;    ;jump to l20, the leave, ret label

l10:
    mov eax, y ; move y into eax
    sub eax, 1 ; y-1
    push eax   ; push y-1 onto stack
    mov ebx, x ; move x into ebx
    push ebx   ; push x onto stack
    call power ; call power/recursion
    add esp, 8 ; add 8 to stack(4*2) for the two vars
    imul eax, x ; multiply the returned value from call by x

l20:
    leave ; leave
    ret   ;ret

直接从此c代码编码:

int power_c(int x, int y) {
    if (y == 0) {
        return 1;
    } else {
        return power_c(x, y - 1)*x;
    }
}

asm代码完美运行,任何建议的调整都很棒,我还是装配新手。我的问题是,我可以用哪些地址来定义参数?在这里,我有两个,我使用:

%define x [ebp+8]
%define y [ebp+12]

如果我有更多,我只是增加它吗?可以说所有都是整数,4字节,就像这样?

%define x [ebp+8]
%define y [ebp+12]
%define z [ebp+16]
%define a [ebp+20]
%define b [ebp+24]

我已经遇到了需要定义更多参数的代码问题,我无法解决这个问题,我们将非常感谢任何帮助。

1 个答案:

答案 0 :(得分:2)

参数在堆栈上传递 - 调用者负责推送它们。功能启动时,该空间已被保留。如果您将原型更改为power_c(int x, int y, int z),则z将位于[ebp+16]

本地变量(或自动)是您的责任。标准方法是从esp中减去所需的空间,正如@Peter Cordes在评论中提到的那样。因此,要创建变量ab,您可以执行以下操作:

sub esp, 8
%define a [ebp+4]
%define b [ebp-8]

请注意,此时ebp == esp+8。我们定义相对于ebp而不是esp的变量,以便您可以继续使用push和pop指令(更改堆栈指针)。在退出函数之前,请务必将esp设置回ebpmov esp, ebp),以便正确找到返回地址。