首页
社区
课程
招聘
[旧帖] [求助]x64汇编如何为变量分配堆栈空间? 0.00雪花
发表于: 2013-7-22 18:26 2234

[旧帖] [求助]x64汇编如何为变量分配堆栈空间? 0.00雪花

2013-7-22 18:26
2234
最近没有网,windbg的符号包有问题,没法进行源码调试。所以有个问题想询问一下网友们。
来看一个MessageBox的x64汇编程序:
extrn MessageBoxA: proc

.data
text     db 'Hello x64!', 0
caption  db 'My First x64 Application', 0

.code
Main proc
sub rsp,28h
xor r9d,r9d
lea r8, caption
lea rdx, text
xor rcx,rcx
call MessageBoxA
add rsp,28h
ret

Main ENDP
end

为什么在MessageBox这个程序里面给MessageBoxA函数分配了28H(4个参数+函数返回地址)的空间,但是象其他的子过程只分配20H的空间,这些子过程的函数最多有4个参数,同样有MessageBoxA函数,为什么只能分配20H空间?
同样的函数,为什么分配空间不同?

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
首先,x64和x86架构稍微有些不同。 有些x64是使用寄存起传递参数,而不是和32位一样的用栈传递参数。
当x64的寄存器传递参数时,不是用rbp作为栈的定位指针,rbp作为通用寄存器使用,所有定位都有rsp决定,因此不能使用rbp定位。

这里的程序正是用寄存器传递参数的。想知道栈空间分配,建议去反汇编x86程序。

http://msdn.microsoft.com/en-us/library/windows/hardware/ff561499(v=vs.85).aspx
这个文章中提到x64的调用约定。由caller保留和参数相对应的栈空间给callee使用(不一定会用到)。

至于问题1,你把栈拉的更低(20h 到28h),但是程序最后还是崩溃了,我觉的是你没有更改完所有rsp有关的指令。比如exit函数里的add rsp, 20h你就没有改成28h

至于为什么messagebox程序里是28h,我也不知道。你可以试试把messagebox程序里的28h改到20h,我感觉也是能运行的。
2013-7-23 10:22
0
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
有人给出解答了:堆栈要16字节对齐。
2013-7-23 18:24
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
这样啊。。
2013-7-23 22:50
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
话说16字节对齐是因为SSE指令。如果没有相关操作,x64下8字节对齐应该就够了
2013-7-24 00:29
0
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
必须16字节对齐,两种情况除外。
堆栈将始终保持 16 字节对齐,以下两种情况除外:一是在 Prolog 中(例如,推入返回地址之后);二是在帧函数特定类的 函数类型 中指示的位置。
2013-7-24 18:51
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
没有必须这一说吧。windows编译器为了性能优化进行16字节对齐。硬件上来讲,没有SSE指令的情况下,整型变量一般不超过8字节,8字节对齐也不会出错
2013-7-25 00:49
0
游客
登录 | 注册 方可回帖
返回
//