为什么GCC-O0通常将第一个局部变量存储在[ebp-4],为什么不总是这样



我目前正在学习使用x86指令集的逆向工程,并且对函数的第一个局部变量始终存储在地址[ebp-4]有着普遍的理解。然而,下面的C函数似乎没有遵循这一原则,我正在努力找出原因:

int check_authentication(char *password) {
int auth_flag = 0;
char buffer[16];
strcpy(buffer, password);
if(strcmp(buffer, "password") == 0)
auth_flag = 1;
return auth_flag; 
}

对于行int auth_flag = 0,我期望相应的x86 ASM转换为mov DWORD PTR[ebp-4], 0。但是,上面函数的已编译ASM输出的第一行如下所示(通过gcc -m32 -O0 [...]编译(:

check_authentication:
push    ebp
mov     ebp, esp
sub     esp, 40
mov     DWORD PTR [ebp-12], 0 ; <- Why ??

为什么它使用内存地址[ebp-12]而不使用[ebp-4]
我认为这与函数中的函数调用有关(即,如果我删除了对strcpystrcmp的调用,则会按预期使用[ebp-4](
我似乎一开始就不明白为什么会发生这种事。

C不是高阶程序集。不能期望编译器逐语句地将C编译为程序集。

x86 ASM中的第一个本地变量是否始终存储在位置[ebp-4]?

不,这会束缚C编译器作者的手脚。

最新更新