VisualStudio2017函数调用栈帧布局分析

需积分: 0 0 下载量 72 浏览量 更新于2024-06-30 收藏 7.15MB DOCX 举报
"函数调用栈帧布局实验1 - 电子科技大学软件开发环境实验,学生任振华,指导教师李林,2019/12/22" 实验主要目标是通过Visual Studio 2017理解函数调用时栈帧布局,包括参数、局部变量的存储以及栈的保护措施。实验基于x86架构,使用的是CISC(复杂指令集计算)的汇编语言,具体是Intel汇编。函数调用过程中,栈帧的构建和销毁是关键,它涉及到了程序执行的上下文切换。 实验原理主要围绕函数调用的标准过程,即调用约定。在C语言中,通常使用标准的stdcall或cdecl约定。在这个实验中,可以看到以下步骤: 1. **建立栈帧**:函数开始时,首先会`push ebp`,保存当前的基址指针(ebp),然后`mov ebp, esp`,更新ebp为当前栈顶指针(esp),这一步创建了新的栈帧。 2. **预留空间**:使用`sub esp, 0C0h`预留空间,用于存储局部变量。这里的0C0h(192)表示预留了192个字节的空间。 3. **保护寄存器**:在某些情况下,编译器会保存ebx、esi和edi寄存器,因为它们可能被函数内部使用。`push ebx`、`push esi`和`push edi`将这些寄存器的值压栈。 4. **初始化操作**:接着,代码可能进行一些初始化操作,如填充栈上预分配的空间。在这个例子中,使用`lea edi, [ebp-0C0h]`设置edi为栈上空间的起始地址,`mov ecx, 30h`设置计数器,`mov eax, 0CCCCCCCCh`设置填充的值,然后使用`rep stosd`循环填充栈上的空间。 5. **恢复寄存器**:函数结束前,`pop edi`、`pop esi`和`pop ebx`将保存的寄存器值弹出并恢复。 6. **销毁栈帧**:`mov esp, ebp`将esp恢复到ebp的值,消除栈帧,`pop ebp`将ebp出栈,最后`ret`指令返回调用者,结束函数调用。 这个实验的目的是让学习者理解函数调用时栈上的动态,如何存储参数、局部变量,以及如何维护函数调用的上下文。通过观察Visual Studio 2017中的调试信息,可以深入理解栈帧的工作原理,这对于理解和排查内存相关的错误,特别是栈溢出问题,具有重要意义。