Windows堆栈上的“额外” 32个字节是什么?

问题描述 投票:0回答:1

我正在学习Windows上的程序集,并试图弄清楚堆栈上的值是什么。Visual C++ documentation说RSP之上的值是:

  • 已分配空间
  • 已保存的RBP
  • 寄信人地址
  • 注册主页(RCX,RDX,R8,R9)
  • 功能参数

问题是文档中没有提到堆栈中有32个额外的字节。

memory snapshot中,RSP从0x0000000000DAF5E0开始。彩色框是:

  • 黄色:两个值为9的64位变量
  • 白色:保存的旧RBP +寄信人地址
  • 蓝色:功能参数
  • 绿色:注册首页
  • 红色:?

红色的那些字节可能是什么?

使用VS2019,MASM64构建并以x64调试模式运行的MASM源代码。

C ++标志:/ JMC / permissive- / GS / W3 / Zc:wchar_t / ZI / Gm- / Od / sdl /Fd"x64\Debug\vc142.pdb“ / Zc:inline / fp:precise / D” _DEBUG “ / D” _CONSOLE“ / D” _UNICODE“ / D” UNICODE“ / errorReport:prompt / WX- / Zc:forScope / RTC1 / Gd / MDd / FC / Fa” x64 \ Debug \“ / EHsc / nologo / Fo” x64 \ Debug \“ /Fp"x64\Debug\ConsoleApplication1.pch” / diagnostics:column

.code

; int64_t StackFrameDemo_(int8_t a, int16_t b, int32_t c, int64_t d, int8_t e, int16_t f, int32_t g, int64_t h)
StackFrameDemo_ proc frame

; prolog
push rbp
.pushreg rbp

; allocate 16 bytes on the stack
sub rsp, 16
.allocstack 16
.endprolog

; save registers to register home
mov qword ptr [rbp+8], rcx
mov qword ptr [rbp+16], rdx
mov qword ptr [rbp+24], r8
mov qword ptr [rbp+32], r9

; save the two variables
mov rax, 9
mov [rsp], rax
mov [rsp+type qword], rax

nop ; set the break point here to view memory

; epilog
add rsp, 16 ; release local stack space
pop rbp     ; restore caller's rbp register

ret

StackFrameDemo_ endp

end
c++ assembly x86-64 masm masm64
1个回答
0
投票

您忘记进行mov rbp, rsp(在push rbp之后),使RBP成为您的堆栈帧中的帧指针。

您的“家庭空间”又名影子空间返回地址上方32字节,您只是不使用它。(并且通过存储相对于某些可能具有寄存器的寄存器而违反了调用约定。任何值。在这种情况下,您的呼叫者可能还将RBP用于旧式帧指针,因此您可能只是踩到了呼叫者的本地空间。)

请注意,0xCC是MSVC调试模式用来中毒堆栈的值,有助于检测未初始化内存的读取。 (并且,如果您不小心用这些内容执行了内存,那是x86 int3调试断点指令。)

[顺便说一句,当您将RBP用作传统的帧指针时,mov rsp, rbp / retadd rsp, 16更有效。代码大小略小,某些CPU进行了移动消除,以避免需要mov的执行单元。对于您来说,这可能会更吵闹,例如,可能是从呼叫者的寄信人地址返回,单步执行时您可能已经注意到了!

© www.soinside.com 2019 - 2024. All rights reserved.