汇编 intel x86 哪些地址可以用来定义参数
Assembly intel x86 which addresses can be used to define arguments
我实际可以使用哪些内存点?
我有这个汇编代码通过递归来为 (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]
我在代码中遇到了问题,我需要定义更多参数,我就是想不通,任何帮助将不胜感激。
参数 在堆栈上传递 - 调用者负责压入它们。 space 在您的函数启动时已被保留。如果您将原型更改为 power_c(int x, int y, int z)
,则 z 将位于 [ebp+16]
。
局部变量(或自动)是你的责任。正如@Peter Cordes 在评论中提到的那样,标准方法是从 esp
中减去您需要的 space。所以要创建变量 a
和 b
,你可以这样做:
sub esp, 8
%define a [ebp+4]
%define b [ebp-8]
注意此时ebp
== esp+8
。我们定义相对于 ebp
而不是 esp
的变量,以便您可以继续使用 push 和 pop 指令(更改堆栈指针)。记得在退出函数前将esp
设置回ebp
(mov esp, ebp
),这样才能正确找到return地址。
我实际可以使用哪些内存点? 我有这个汇编代码通过递归来为 (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]
我在代码中遇到了问题,我需要定义更多参数,我就是想不通,任何帮助将不胜感激。
参数 在堆栈上传递 - 调用者负责压入它们。 space 在您的函数启动时已被保留。如果您将原型更改为 power_c(int x, int y, int z)
,则 z 将位于 [ebp+16]
。
局部变量(或自动)是你的责任。正如@Peter Cordes 在评论中提到的那样,标准方法是从 esp
中减去您需要的 space。所以要创建变量 a
和 b
,你可以这样做:
sub esp, 8
%define a [ebp+4]
%define b [ebp-8]
注意此时ebp
== esp+8
。我们定义相对于 ebp
而不是 esp
的变量,以便您可以继续使用 push 和 pop 指令(更改堆栈指针)。记得在退出函数前将esp
设置回ebp
(mov esp, ebp
),这样才能正确找到return地址。