【发布时间】:2010-05-06 05:39:15
【问题描述】:
我有一些函数代码
subl $24, %esp
movl 8(%ebp), %eax
cmpl 12(%ebp), %eax
在代码之前只是“ENTER”命令,之后有一个 if 语句,如果 ebp > eax 则返回 1,如果小于则返回 0。我假设 cmpl 的意思是比较,但我不知道具体的值是什么。谁能告诉我发生了什么?
【问题讨论】:
标签: c assembly x86 translation
我有一些函数代码
subl $24, %esp
movl 8(%ebp), %eax
cmpl 12(%ebp), %eax
在代码之前只是“ENTER”命令,之后有一个 if 语句,如果 ebp > eax 则返回 1,如果小于则返回 0。我假设 cmpl 的意思是比较,但我不知道具体的值是什么。谁能告诉我发生了什么?
【问题讨论】:
标签: c assembly x86 translation
Yes cmpl 表示比较(使用 4 字节参数)。假设这段代码后面跟着一个jg <addr>:
movl 8(%ebp), %eax
cmpl 12(%ebp), %eax
jg <addr>
那么代码类似
eax = ebp[8];
if (eax > ebp[12])
goto <addr>;
【讨论】:
%eax 是 [l]ess than ebp[12])。应该可以帮助你快速阅读代码
您的代码片段类似于某些处理器和编译器使用的入口代码。 入口代码是编译器在输入函数时发出的汇编代码。
入口代码负责保存函数参数并为局部变量分配空间并可选择初始化它们。入口代码使用指向变量存储区域的指针。一些处理器使用 EBP 和 ESP 寄存器的组合来指向局部变量(和函数参数)的位置。
由于编译器知道变量(和函数参数)的存储位置,它会删除变量名称并使用数字索引。例如,这行:
movl 8(%ebp), %eax
要么将第 8 个局部变量的内容移动到寄存器 EAX,要么将值从局部区域的开头移动 8 个字节(假设 EBP 寄存器指针指向局部变量的开头区域)。
指令:
subl $24, %esp
暗示编译器在堆栈上保留 24 个字节。这可能是为了保护函数调用约定中的一些信息。该功能将能够在此之后使用该区域以供自己使用。这个保留区可能包含函数参数。
您提供的代码片段看起来像是在比较函数内的两个局部变量:
void Unknown_Function(long param1, long param2, long param3)
{
unsigned int local_variable_1;
unsigned int local_variable_2;
unsigned int local_variable_3;
if (local_variable_2 < local_variable_3)
{
//...
}
}
尝试反汇编上述函数,看看它与您的代码片段的匹配程度。
【讨论】:
这是 (EBP + 8) 和 (EBP + 12) 之间的比较。 cmpl 指令根据比较结果设置后续跳转指令使用的标志。
在Mac OS X 32 bit ABI中,EBP + 8 是第一个函数参数,EBP + 12 是第二个参数。
【讨论】: