我在C中编写汇编语言。我得到了以下汇编代码:
fn:
pushl %ebp
movl %esp, %ebp
subl $16, %esp
movl $1, -4(%ebp)
jmp .f2
.f3:
movl -4(%ebp), %eax
imull 8(%ebp), %eax
movl %eax, -4(%ebp)
subl $1, 8(%ebp)
.f2:
cmpl $1, 8(%ebp)
jg .f3
movl -4(%ebp), %eax
leave
ret
我在C下面写了我的代码:
fn (int x)
{
int y = 1;
if(x > 1):
int z = y *= x
x – 1;
return z;
}
有人能告诉我我的C代码是否在正确的轨道上?或者,如果我不在,如果我是,你可以指出我正确的方向。 先谢谢你了
答案 0 :(得分:2)
fn:
pushl %ebp
movl %esp, %ebp
这是calling convertion __cdecl
中常用的函数启动,将现有%ebp
保存到堆栈然后将%esp
(当前堆栈地址)保存到{{1} }。 %ebp
将从现在起对汇编代码用来访问参数和局部变量的函数的堆栈调用点的引用。为了结束这个功能,将来会做相反的事情,并设置" return"价值为%ebp
。
此时,您可以假设%eax
指向存储前一个%ebp
的当前堆栈位置,%ebp
是函数的返回点,以及来自{的所有内容{1}} on是函数参数的数据。负值将访问未使用的堆栈空间,其中函数可以存储它的局部变量。
%ebp + 4
这是在堆栈中为局部变量保留22个字节的信息。它可以是22个字节的22个变量或22个字节的1个变量,没有办法知道。它可以保留未使用的字节以生成stack alignment。
此时更改%ebp + 8
的值非常重要,因此对 subl $16, %esp
,%esp
和push
的任何调用都不会覆盖此功能'局部变量。
pop
这里可以假设此函数中存在的第一个局部变量是地址call
处的32位整数。它的值只设置为1.让我们调用此变量 movl $1, -4(%ebp)
。
%ebp - 4
根据i
的作用,我们可以假设该函数在地址 jmp .f2
.f3:
movl -4(%ebp), %eax
imull 8(%ebp), %eax
至少采用一个参数,并且它似乎是一个32位整数乘以imull
。让我们调用此参数%ebp + 8
。
i
到目前为止,我们可以假设x
。
movl %eax, -4(%ebp)
现在i = x * i
。
subl $1, 8(%ebp)
这里我们检查x = x - 1
是否大于1.如果为true,则跳转到.f2:
cmpl $1, 8(%ebp)
jg .f3
,这是一个向后跳跃,因此我们似乎有一个循环正在进行。
x
在循环外部,我们看到它将f3
设置为 movl -4(%ebp), %eax
leave
ret
并终止该函数,我们可以将其解释为%eax
。
将分析的信息一起编译,我们可以假设原始函数必须看起来像这样:
i