首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >与x86_64窗口调用约定混淆

与x86_64窗口调用约定混淆
EN

Stack Overflow用户
提问于 2012-09-02 13:27:51
回答 1查看 649关注 0票数 1

平台是x86_64 Windows7。

下面是C语言的源代码:

代码语言:javascript
复制
#include<windows.h>
int main(void){
    asm("int3");
    CreateWindowEx(0,NULL,NULL,0,5,6,7,8,NULL,NULL,NULL,NULL);
    return(0);
}

该程序集编译为以下程序集:

代码语言:javascript
复制
push rbp
mov rbp,rsp
sub rsp,60h
int3
mov qword[rsp+58h],0
mov qword[rsp+50h],0
mov qword[rsp+48h],0
mov qword[rsp+40h],0
mov qword[rsp+38h],8
mov qword[rsp+30h],7
mov qword[rsp+28h],6
mov qword[rsp+20h],5
mov r9d,0
mov r8d,0
mov edx,0
mov ecx,0
call CreateWindowEx
mov eax,0
add rsp,60h
pop rbp
ret

从概念上讲,这是我在不同执行点的堆栈(地址是任意的):

代码语言:javascript
复制
90 -rsp-

90 old rbp
88 -rsp-

90 old rbp
88 -rsp- -rbp-

90 old rbp
88 -rbp- (never used?)
80 (rsp+58h)
78 (rsp+50h)
70 (rsp+48h)
68 (rsp+40h)
60 (rsp+38h)
58 (rsp+30h)
50 (rsp+28h)
48 (rsp+20h)
40 (shadow)
38 (shadow)
30 (shadow)
28 -rsp- (shadow) (will contain call instruction's return pointer...)

正如您所看到的,根据C程序的编译输出,堆栈存在问题。首先,有8个字节永远不会被使用,并且8个字节的影子空间将被返回指针的call指令覆盖。似乎所有东西都比正常情况下移了8个字节,因为如果它向上移动8个字节就可以了。然而,API调用就像预期的那样工作,这仅仅是忽略了Microsoft对调用约定的实现吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-09-02 17:43:07

当一些东西被推到堆栈上时,新的项目不会到达指令开始时rsp所指向的地方- rsp在存储新项目之前会递减(即,rsp指向的堆栈位置正在使用中)。

因此,如果在启动该函数时为rsp ==0x90,则旧的rbp将位于地址0x88 (并且rbp将指向该地址)。

然后,当执行rsp == 0x28call指令时,返回地址将放在地址0x20中,而不是0x28中。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12233648

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档