当前位置: 首页 > news >正文

vs2022 x64 C/C++和汇编混编 遇到的坑

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 endp

2.问题分析

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 字节对齐的。为了确保这一点,我们需要根据保存的寄存器数量来决定是否要调整堆栈指针。

奇数和偶数个寄存器的影响

  1. 奇数个寄存器:

    • 每个 push 指令都会将堆栈指针减少 8 个字节
    • 如果你保存奇数个寄存器(例如1、3、5个寄存器),堆栈指针会减少一个不是 16 字节的倍数的值(如 8、24、40 个字节)。
    • 这时,堆栈指针的对齐就会被破坏,从而导致后续函数调用时堆栈不是 16 字节对齐的。
  2. 偶数个寄存器:

    • 如果你保存偶数个寄存器(例如 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 字节对齐的,所以不需要进行额外的调整。

这个技巧帮助你在函数调用时确保堆栈的对齐性,从而避免潜在的问题。

相关文章:

vs2022 x64 C/C++和汇编混编 遇到的坑

vs2022 x64 C/C和汇编混编 遇到的坑 遇到的问题二、问题复现1.出错代码2.问题分析2.1 堆栈对齐问题 3.解决方案 总结奇数和偶数个寄存器的影响为什么 sub rsp, 8 对奇数个寄存器有用?结论 遇到的问题 0x00007FFFFAE24A29 (msvcp140.dll)处(位于 TestCompileConsole…...

PHP概述、环境搭建与基本语法讲解

目录 【学习目标、重难点知识】 什么是网站? 1. PHP 介绍 1.1. PHP 概述 1.1.1. PHP 是什么? 1.1.2. PHP 都能做什么? 1.2. PHP 环境搭建 1.2.1. PhpStudy 2. PHP 基本语法 2.1. PHP 语法入门 2.1.1. 第一个 PHP 程序 2.1.2. PHP …...

实现信创Linux麦克风摄像头录制(源码,银河麒麟、统信UOS)

随着信创国产化浪潮的来临,在国产操作系统上的应用开发的需求越来越多,其中一个就是需要在银河麒麟或统信UOS上实现录制摄像头视频和麦克风声音,将它们录制成一个mp4文件。那么这个要如何实现了? 一. 技术方案 要完成这些功能&a…...

深度学习9--目标检测

1.概念介绍 目标检测不仅可以检测数字,而且可以检测动物的种类、汽车的种类等。例如,自动驾驶车辆需要自动识别前方物体是车辆还是行人,需要自动识别道路两 旁的指示牌和前方的红绿灯颜色。对于自动检测的算法,有两个要求&#xf…...

第131天:内网安全-横向移动Kerberos 攻击SPN扫描WinRMWinRSRDP

案例一:域横向移动-RDP-明文&NTLM RDP利用的三种方式 1.直接在当前被控主机上进行远程连接 2.建立节点进行连接 3.端口转发,(访问当前主机的2222端口等于访问目标的3389) 第一种方式(动静太大) 直接利用被控主机进行远程连接…...

微信小程序的四种弹窗使用

​ 在做小程序的过程中,弹窗也算是非常实用的功能了,这几天写的几个功能就用到了弹窗,也可能是初学者的问题,比较菜,想找一个可以带图片的自定义的弹窗,,这里简单介绍一下官方封装好的四个弹窗…...

我的第一个CUDA程序

MatAdd算法 实现两个矩阵对应元素相加 #include <stdio.h> #include <stdlib.h>// 矩阵加法函数 void MatAdd(int height, int width) {// 在主机内存中为 A、B 和 C 分配内存float* A (float*)malloc(height * width * sizeof(float));float* B (float*)malloc…...

workerman下的webman路由浏览器跨域的一种问题

软件版本 "php": ">7.2", "workerman/webman-framework": "^1.5.0",问题情景 使用“分组路由”做API接口前后端分离跨域&#xff0c;在接口测试工具调试是能正常获取数据的&#xff1b;但在网页浏览器上调试就遇到了CORS、404的错…...

Windows11 -MASKRCNN-部署测试

文章目录 Detectron2环境配置搭建python 环境安装Cuda \CUDNN 、PyTorch、 torchvision、cudatoolkit1、Cuda \CUDNN2、 PyTorch、 torchvision、cudatoolkit进入python测试&#xff1a;错误信息 3、detectron2环境在安装detecteron中&#xff0c;遇到报错&#xff1a;编译的时…...

函数(子程序)的常见、易混淆概念详解【对初学者有帮助】

C语⾔中的函数也被称做子程序&#xff0c;意思就是⼀个完成某项特定的任务的⼀小段代码。 C语⾔标准中提供了许多库函数&#xff0c;点击下面的链接可以查看c语言的库函数和头文件。 C/C官⽅的链接&#xff1a;https://zh.cppreference.com/w/c/header 目录 一、函数头与函…...

TiDB-从0到1-DM工具

TiDB从0到1系列 TiDB-从0到1-体系结构TiDB-从0到1-分布式存储TiDB-从0到1-分布式事务TiDB-从0到1-MVCCTiDB-从0到1-部署篇TiDB-从0到1-配置篇TiDB-从0到1-集群扩缩容TiDB-从0到1-数据导出导入TiDB-从0到1-BR工具 一、DM原理 支持全量抽取数据\检测新的数据变化同步到下游实例…...

AppScan——Web 应用安全扫描的得力工具

一、引言 在当今数字化时代&#xff0c;Web 应用成为企业业务的重要支撑&#xff0c;但同时也面临着各种安全威胁。AppScan 作为一款专业的 Web 应用安全扫描工具&#xff0c;为保障 Web 应用的安全性提供了有力的支持。本文将对 AppScan 进行详细介绍&#xff0c;包括其功能、…...

虚幻5|AI行为树,进阶篇

一&#xff0c;打开敌人的角色蓝图&#xff0c;编写以下蓝图&#xff0c;该蓝图只是创建一个敌人并非ai行为树 1.编写蓝图 2.打开主界面&#xff0c;创建一个导航网格体积&#xff0c;上一章都有讲&#xff0c;在添加体积这里面&#xff0c;找到导航网格体积&#xff0c;点击创…...

在 Spring Boot 中配置 Tomcat 监听多个端口

在现代微服务架构中&#xff0c;应用程序可能需要监听多个端口&#xff0c;以支持不同的服务或协议。Spring Boot 提供了灵活的配置选项&#xff0c;使得这一需求变得简单而高效。本文将介绍如何在 Spring Boot 中配置 Tomcat 以监听多个端口&#xff0c;并简要说明其中一些关键…...

stm32f407新建项目工程及烧录

1、新建一个文件夹&#xff0c;打开keil5将项目工程放入文件夹中 2、弹出选择对应型号设备 3、弹出选择对应库 可以看见出现下图&#xff1a;感叹号表示有错 最后如图所示&#xff1a;点击ok就行了 4、创建对应的文件夹存放文件 4、建立main.c 5、添加对应的设置 最后写一个空白…...

c++中加不加const的值传递和引用传递的区别

文章目录 可以修改参数值的比较值传递(int x)和引用传递(int &x)使用const不修改参数值的比较值传递(const int x)和引用传递(const int &x)1. const int x 示例2. const int &x 示例 可以修改参数值的比较值传递(int x)和引用传递(int &x) #include <iost…...

Qt的窗口设置

本文介绍Qt的窗口设置。 采用Qt开发界面程序&#xff0c;会涉及到窗口的设置&#xff0c;如窗口标题栏是否显示&#xff0c;是否有最小&#xff0c;最大化按钮等&#xff0c;窗口当前显示最小化&#xff0c;最大化等。本文简要介绍常用的窗口设置方法。 1.窗口属性 窗口属性…...

51单片机-LCD1602显示屏

简介 是一个液晶显示屏&#xff0c;通过电压对显示区域进行控制&#xff0c;有电就显示。 能够同时显示32个字符&#xff0c;分为两行&#xff0c;一行显示16个字符。可以显示的内容只能是字母、数字或者一些特殊符号。 使用ASCII码来让LCD1602来显示对应的字符。 电路图 …...

多模态分析代理 MAIA:多智能体解决 视觉模型 黑盒问题

多模态分析代理 MAIA&#xff1a;多智能体解决 视觉模型 黑盒问题 论文&#xff1a;https://arxiv.org/pdf/2404.14394 代码&#xff1a;https://github.com/multimodal-interpretability/maia 提出背景 神经网络方法提取的特征&#xff0c;没有可解释性。 数据在通过多个层…...

AT360-6T杭州中科微单频高精度授时模块场景应用

AT360-6T是一款高性能多系统卫星定位授时模块&#xff0c;基于自主研发的北斗多系统SOC芯片&#xff0c;可以同时接收中国的BDS(北斗二号和北斗三号)、美国的GPS、俄罗斯的GLONASS、欧盟的 GALILEO 和日本的QZSS等多个卫星导航系统的GNSS信号来实现多系统联合定位授时&#xff…...

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题&#xff1a; 下面创建一个简单的Flask RESTful API示例。首先&#xff0c;我们需要创建环境&#xff0c;安装必要的依赖&#xff0c;然后…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

GitFlow 工作模式(详解)

今天再学项目的过程中遇到使用gitflow模式管理代码&#xff0c;因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存&#xff0c;无论是github还是gittee&#xff0c;都是一种基于git去保存代码的形式&#xff0c;这样保存代码…...

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版&#xff0c;莫兰迪调色板清新简约工作汇报PPT模版&#xff0c;莫兰迪时尚风极简设计PPT模版&#xff0c;大学生毕业论文答辩PPT模版&#xff0c;莫兰迪配色总结计划简约商务通用PPT模版&#xff0c;莫兰迪商务汇报PPT模版&#xff0c;…...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分&#xff1a;派生类构造函数与析构函数 当创建一个派生类对象时&#xff0c;基类成员是如何初始化的&#xff1f; 1.当派生类对象创建的时候&#xff0c;基类成员的初始化顺序 …...

android RelativeLayout布局

<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...

【堆垛策略】设计方法

堆垛策略的设计是积木堆叠系统的核心&#xff0c;直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法&#xff0c;涵盖基础规则、优化算法和容错机制&#xff1a; 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则&#xff1a; 大尺寸/重量积木在下&#xf…...

【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统

Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...

前端工具库lodash与lodash-es区别详解

lodash 和 lodash-es 是同一工具库的两个不同版本&#xff0c;核心功能完全一致&#xff0c;主要区别在于模块化格式和优化方式&#xff0c;适合不同的开发环境。以下是详细对比&#xff1a; 1. 模块化格式 lodash 使用 CommonJS 模块格式&#xff08;require/module.exports&a…...

生信服务器 | 做生信为什么推荐使用Linux服务器?

原文链接&#xff1a;生信服务器 | 做生信为什么推荐使用Linux服务器&#xff1f; 一、 做生信为什么推荐使用服务器&#xff1f; 大家好&#xff0c;我是小杜。在做生信分析的同学&#xff0c;或是将接触学习生信分析的同学&#xff0c;<font style"color:rgb(53, 1…...