建筑设计师网站,网站建设是什么部门,网站开发公司谁家好,网站建设方案书写vs2022 x64 C/C和汇编混编 遇到的坑 遇到的问题二、问题复现1.出错代码2.问题分析2.1 堆栈对齐问题 3.解决方案 总结奇数和偶数个寄存器的影响为什么 sub rsp, 8 对奇数个寄存器有用#xff1f;结论 遇到的问题
0x00007FFFFAE24A29 (msvcp140.dll)处(位于 TestCompileConsole… vs2022 x64 C/C和汇编混编 遇到的坑 遇到的问题二、问题复现1.出错代码2.问题分析2.1 堆栈对齐问题 3.解决方案 总结奇数和偶数个寄存器的影响为什么 sub rsp, 8 对奇数个寄存器有用结论 遇到的问题
0x00007FFFFAE24A29 (msvcp140.dll)处(位于 TestCompileConsoleApp.exe 中)引发的异常: 0xC0000005: 读取位置 0xFFFFFFFFFFFFFFFF 时发生访问冲突。 查阅资料发现异常 0xC0000005: Access Violation 表示程序试图访问一个无效的内存地址。在你的情况下读取地址 0xFFFFFFFFFFFFFFFF 发生了访问冲突。这通常意味着你试图访问一个无效的指针或未初始化的指针。
— # 一、pandas是什么 示例pandas 是基于NumPy 的一种工具该工具是为了解决数据分析任务而创建的。
二、问题复现
1.出错代码
代码如下示例
capp procsub rsp, 28h ; 为局部变量和寄存器保存空间; 保存所有需要的寄存器push raxpush rcxpush rdxpush r8push r9push r10push r11; 自定义代码mov rcx, 10 ; 将参数传递给RCX寄存器call hookFunc ; 调用hookFunc函数; 恢复所有寄存器pop r11pop r10pop r9pop r8pop rdxpop rcxpop raxadd rsp, 28h ; 恢复堆栈指针ret
capp endp2.问题分析
2.1 堆栈对齐问题
在 x64 汇编中函数调用时堆栈指针RSP必须是 16 字节对齐的。如果你在调用函数前通过 push 指令保存了寄存器堆栈指针会减少 8 个字节这可能会导致堆栈不对齐。
3.解决方案 capp procsub rsp, 28h ; 为局部变量和寄存器保存空间; 保持堆栈对齐sub rsp, 8; 保存寄存器push raxpush rcxpush rdxpush r8push r9; 调用你的函数mov rcx, 10call hookFunc; 恢复寄存器pop r9pop r8pop rdxpop rcxpop rax; 恢复堆栈对齐add rsp, 8add rsp, 28h ; 恢复堆栈指针ret
capp endp如果保存寄存器的数量是奇数个可以通过手动调整来保证堆栈对齐。例如使用 sub rsp, 8 手动调整堆栈指针使其对齐到 16 字节。 总结
在 x64 汇编中堆栈的对齐要求是函数调用时堆栈指针RSP必须是 16 字节对齐的。为了确保这一点我们需要根据保存的寄存器数量来决定是否要调整堆栈指针。
奇数和偶数个寄存器的影响 奇数个寄存器: 每个 push 指令都会将堆栈指针减少 8 个字节。如果你保存奇数个寄存器例如1、3、5个寄存器堆栈指针会减少一个不是 16 字节的倍数的值如 8、24、40 个字节。这时堆栈指针的对齐就会被破坏从而导致后续函数调用时堆栈不是 16 字节对齐的。 偶数个寄存器: 如果你保存偶数个寄存器例如 2、4、6 个寄存器堆栈指针减少的值会是 16 字节的倍数如16、32、48个字节。在这种情况下堆栈指针的对齐不会被破坏因此不需要进行额外的调整。
为什么 sub rsp, 8 对奇数个寄存器有用
当你保存奇数个寄存器时堆栈指针被推到一个不是 16 字节对齐的地址。通过在保存寄存器之前执行 sub rsp, 8你可以先手动将堆栈指针调整到一个不对齐的状态接下来每次 push 操作都会在最终使堆栈指针回到对齐的状态。
具体来说
sub rsp, 8 手动将 RSP 移动 8 个字节使其暂时不对齐。然后每次 push 操作都会进一步移动 RSP 8 个字节。如果你总共 push 奇数个寄存器RSP 将恢复到对齐的状态。
结论
奇数个寄存器: 你需要通过 sub rsp, 8 手动调整堆栈指针以确保保存和恢复寄存器后堆栈指针是 16 字节对齐的。偶数个寄存器: 由于堆栈指针在保存和恢复寄存器前后仍然是 16 字节对齐的所以不需要进行额外的调整。
这个技巧帮助你在函数调用时确保堆栈的对齐性从而避免潜在的问题。