标题:64位汇编 调用规范里的 32字节的 影子空间啥作用啊
只看楼主
pqw321
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2021-7-25
结帖率:0
已结贴  问题点数:20 回复次数:3 
64位汇编 调用规范里的 32字节的 影子空间啥作用啊
x64调用规范
第3行
调用者的责任,还包括在运行时堆栈分配至少32字节的影子空间,这样被调用的过程就可以选择将计算器参数保存在这个区域中。
问题这里的影子空间32字节,我咋没看出来是啥意思以及它们的作用。
图片在博客里
https://blog.bccn.net/attachments/1679
https://blog.bccn.net/attachments/1680

https://blog.bccn.net/attachments/1679

https://blog.bccn.net/attachments/1681

https://blog.bccn.net/attachments/1682


[此贴子已经被作者于2021-7-25 21:32编辑过]

搜索更多相关主题的帖子: bccn blog https 调用 net 
2021-07-25 21:24
pqw321
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2021-7-25
得分:0 
回复 楼主 pqw321
我的天啊这图片咋弄上去啊。。。
2021-07-25 21:32
pqw321
Rank: 1
等 级:新手上路
帖 子:3
专家分:0
注 册:2021-7-25
得分:0 
其实就是主调程序 为被调用程序预留的 4个 64位存储空间 可通过**_直接寻址方式******_访问。。这是WINDOWSAPI 64 的规范。具体用不用如何使用是 WINDOWS API 的事情(外部调用过程 无法自己修改)一般来说是用来暂存 传递参数的寄存器的值得 腾出来寄存器 以便 外部库过程使用。且外部库过程使用堆栈结束后需清除所有参数使用的堆栈空间和影子空间 需把堆栈指针复原到RSP指针未因为外部库过程而被修改之前的地址。

[此贴子已经被作者于2021-7-26 20:40编辑过]

2021-07-26 18:49
Valenciax
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:11
帖 子:337
专家分:2462
注 册:2016-5-15
得分:20 
Win64 有呼叫协定,‘呼叫协定 ( calling convention )’。在 Win32 汇编语言中,呼叫 Win API 是以堆栈传递参数,且最右边的参数先推入堆栈,传回值存于 EAX 暂存器里,并且由被呼叫的一方 ( 即副程式或 API,像这种被呼叫的程式称为 callee ) 清除堆栈,此种呼叫协定称为‘STDCALL’。但是在 Win64 却有底下不同:

参数的传递并非完全靠堆栈,而是靠暂存器以及堆栈;精确的说,前四个参数依序放在 ECX、EDX、R8、R9 暂存器里面,第五个以后的参数才放在堆栈里。
主程式 ( 或称为呼叫者,caller ) 必须为副程式或 API ( 或称为被呼叫者,callee )准备好足够的堆栈空间,以容纳这些参数。每个参数占用四字组 ( QWORD ),亦即 8 个字节 ( BYTE )。

即使前四个参数靠暂存器传递给副程式或 API,但是主程式仍然得准备 32 个字节的堆栈空间,以保留给前四个参数存入;甚至连不到四个参数的 API 也得在堆栈准备 32 个字节的空间!假如您没有准备好足够的堆栈空间,程式必定崩溃。

当程式由副程式返回时,由主程式 ( caller,呼叫者 ) 负责清除堆栈,而不是副程式或 API 清除堆栈。
堆栈框必须对齐一个节 ( paragraph ),每个节的大小是 16 个字节,即十六进位的 10H。换句话说,堆栈框必须要在堆栈位址的 WWWWXXXXYYYYZZZ0H 处。或者说,堆栈框所在的堆栈位址必须要能被 10H 整除。
这种呼叫协定称为‘FASTCALL’( 有些文献是说类似 FASTCALL )。举个例子来说明,可能会清楚一点。例如要呼叫 MessageBox API 时,在 Win32 底下为:

        INVOKE  MessageBox,hWnd,OFFSET lpText,OFFSET lpCaption,MB_OKCANCEL

一行就解决了,但是在 Win64 里,却变成

.CODE
;-------------------------------------------------------------------------------
Main    PROC
        sub     rsp,28h            ;保留4个8字节的参数+1个8字节返回值
        mov     r9,MB_OKCANCEL
        mov     r8,OFFSET szTitle
        mov     rdx,OFFSET szText
        sub     rcx,rcx
        call    MessageBoxA
        add     rsp,28h            ;主程序负责清除堆栈
        ret
Main    ENDP
;*******************************************************************************
        END

[此贴子已经被作者于2021-7-27 16:08编辑过]

2021-07-27 06:00



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-506328-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.258573 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved