X86_64函数调用汇编程序分(2)

X86_64函数调用汇编程序分(2)

  • 1 X86_64寄存器使用标准
  • 2 leaveq和retq指令
    • 2.1 leaveq
    • 2.2 retq
  • 3 执行leaveq和retq之后栈的结构
    • 3.1 执行leaveq之后栈的结构
      • 3.1.1 test_fun_b函数执行leaveq之前的栈结构示意图
      • 3.1.2 test_fun_b函数执行leaveq之后的栈结构示意图
    • 3.2 执行retq之后栈的结构
      • 3.2.1 test_fun_b函数执行retq之前的栈结构示意图
      • 3.2.2 test_fun_b函数执行retq之后的栈结构示意图

X86_64函数调用汇编程序分析

1 X86_64寄存器使用标准

  • %rdi, %rsi, %rdx, %rcx, %r8, %r9分别用于函数调用过程中的前6个参数,对于6的参数存放在栈中传递
  • %rsp用做栈指针寄存器,指向栈顶
  • %rbp用作栈框寄存器,指向栈底
  • %rax用做函数返回值的第一个寄存器
  • %rip寄存器可以当做PC寄存器(程序计数器)使用。它用于存储下一条要执行的指令的地址。[ In 64-bit mode, the RIP register becomes the instruction pointer. This register holds the 64-bit offset of the next instruction to be executed. 64-bit mode also supports a technique called RIP-relative addressing. Using this technique, the effective address is determined by adding a displacement to the RIP of the next instruction.(在 64 位模式下,RIP 寄存器成为指令指针。该寄存器保存下一条要执行指令的 64 位偏移量。64 位模式还支持一种称为 RIP 相对寻址的技术。使用这种技术,有效地址是通过在下一条指令的 RIP 中加入一个位移来确定的。) ]
    在这里插入图片描述

2 leaveq和retq指令

2.1 leaveq

x86_64架构的leaveq指令是一个伪指令,它并不是一条单独的指令,而是由两条实际指令组合而成的。具体来说,leaveq的功能等效于pop %rbp; mov %rbp, %rsp这两条指令。

首先,让我们来了解一下这两条指令的含义:

mov %rbp, %rsp:这条指令将栈指针寄存器%rbp的值复制到基指针寄存器%rsp中。在x86_64架构中,%rsp寄存器用于保存当前线程的栈指针,指向栈顶位置。而%rbp寄存器通常用作基指针,指向函数调用堆栈的底部。
pop %rbp:这条指令弹出栈顶的值并将其存储在%rbp寄存器中。在函数调用过程中,%rbp寄存器的值通常被保存起来,用于在函数返回时恢复函数调用堆栈的状态。
那么,为什么需要这两条指令的组合呢?在x86_64架构中,当函数调用发生时,处理器会将函数的参数和局部变量压入栈中,同时保存一些寄存器的值(如%rbp)以供函数内部使用。当函数执行完毕并准备返回时,需要恢复这些寄存器的值并清理栈中的局部变量。这就是leaveq伪指令的作用。

通过执行mov %rbp, %rsp和pop %rbp这两条指令,可以将栈指针的值复制到%rbp寄存器中,并弹出栈顶的值恢复%rbp寄存器的原始值。这样,函数返回后,栈指针和基指针的值都得到了恢复,保证了程序的正确执行。

需要注意的是,leaveq伪指令的执行并不会改变任何寄存器的值,只会影响栈指针和基指针的状态。因此,它通常用于函数返回之前的准备阶段,以确保正确的控制流和栈状态。

总结一下,x86_64架构的leaveq伪指令是一个用于恢复函数调用堆栈状态的指令组合,它等效于mov %rbp, %rsp; pop %rbp这两条实际指令的功能。在执行leaveq后,栈指针和基指针的值会得到恢复,为函数返回做好准备。

2.2 retq

x86_64架构中的retq指令是用于从当前函数调用中返回的指令。在函数调用完成后,retq指令会将控制权返回给调用者,同时恢复堆栈状态和寄存器的值。

首先,让我们来了解一下retq指令的作用。当函数执行到retq指令时,处理器会从当前函数调用的堆栈中弹出返回地址,并将控制流转移到该地址处。这个地址通常是在函数调用时被压入栈中的。因此,在函数返回时,控制权会返回到调用该函数的地方。

在执行retq指令时,处理器还会恢复一些寄存器的值。例如,在函数调用发生时,基指针寄存器%rbp的值通常会被保存起来,用于在函数返回时恢复堆栈的状态。同样地,栈指针寄存器%rsp的值也可能会被保存和恢复。这些操作是隐式的,不需要程序员显式地编写指令来完成。

另外,关于retq指令的执行时机,它通常出现在函数的末尾,即当函数的所有操作都完成后才会执行。在某些情况下,如果函数使用了递归或者其他更复杂的控制流程,可能会在更早的时候使用retq指令来提前返回。但是,在函数执行完毕之前使用retq指令是不允许的,否则会导致程序崩溃或其他错误。

需要注意的是,如果使用汇编语言来编写程序,通常需要根据具体的架构和编译器来编写代码。虽然x86_64架构中的retq指令可以用来实现函数返回的操作,但是使用汇编语言编写程序需要考虑到很多细节和注意事项,包括对寄存器的使用、内存访问以及其他底层操作的处理。因此,除非必要,否则建议尽可能使用高级语言来编写程序,以避免出现一些难以预料的问题。

总之,x86_64架构中的retq指令是用于从当前函数调用中返回的指令。它通过弹出堆栈中的返回地址并将控制流转移到该地址来实现函数返回的操作。同时,一些寄存器的值也会得到恢复,以确保程序在返回之前处于正确的状态。

3 执行leaveq和retq之后栈的结构

3.1 执行leaveq之后栈的结构

3.1.1 test_fun_b函数执行leaveq之前的栈结构示意图

在这里插入图片描述

3.1.2 test_fun_b函数执行leaveq之后的栈结构示意图

在test_fun_b调用leaveq之后,test_fun_b的栈空间就会被释放掉,该指令执行的操作为:

pop %rbp
mov %rbp, %rsp;

在这里插入图片描述

3.2 执行retq之后栈的结构

通常情况下,leaveq和retq是依次被调用到的。leaveq是为了恢复%rsp寄存器的值,而ret会把返回地址从栈中弹出并将%rip指向弹出的返回地址。

3.2.1 test_fun_b函数执行retq之前的栈结构示意图

在这里插入图片描述

3.2.2 test_fun_b函数执行retq之后的栈结构示意图

retq会把返回地址从栈从弹出,并更新%rip寄存器的值为返回地址的值,同时也会更新%rsp寄存器的值。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/131120.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JSP SSM 成果展示系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 JSP SSM 冬奥建设成果展示系统是一套完善的web设计系统(系统采用SSM框架进行设计开发,springspringMVCmybatis),对理解JSP java编程开发语言有帮助,系统具有完整的 源代码和数据库,系统主…

ubuntu基本配置

记录一下每次重新安装系统之后都要进程的操作 更新源 更新源的教程 sudo bash -c "cat << EOF > /etc/apt/sources.list && apt update deb http://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse deb-src http://mirrors.a…

LLM - 数据处理之 Process Dataset For LLM With PT、SFT、RM

目录 一.引言 二.PT 数据流程 1.数据样式 2.生成代码 3.数据生成 三.SFT 数据流程 1.数据样式 2.生成代码 3.数据生成 四.RM 数据流程 1.生成逻辑 2.RM 模型测试 五.总结 一.引言 上篇文章 LLM - 批量加载 dataset 并合并介绍了如何加载多个文件并合成一个 datas…

leetcode:67. 二进制求和

题目&#xff1a; 函数原型&#xff1a; char * addBinary(char * a, char * b) 思路&#xff1a; 二进制相加&#xff0c;首先我们考虑先将字符串逆序。由此要写一个逆序函数reserve。字符串逆序后&#xff0c;从前往后相加&#xff0c;以较长的字符串的长度为标准长度n&#…

【光谱超分辨率:综述】

Spectral super-resolution meets deep learning: Achievements and challenges &#xff08;面向深度学习的光谱超分辨率&#xff1a;成就和挑战&#xff09; 光谱超分辨率是一种从RGB图像获取高光谱图像的重要技术&#xff0c;可以有效地克服高光谱图像获取成本高、空间分辨…

vite + react + typescript + uni-app + node 开发一个生态系统

简介 使用 vite react typescript uni-app node 来开发一个简易的生态系统案例&#xff0c;包含 APP&#xff0c;H5&#xff0c;微信小程序&#xff0c;控制台&#xff0c;服务端 开发 admin 技术栈&#xff1a;vite react typescript初始化控制台项目选择自定义预设…

Gitlab仓库部署

Gitlab仓库部署 一、Gitlab的概述1、gitlab介绍2、gitlab主要功能3、gitlab和github的区别 二、部署环境1、安装依赖环境2、安装Postfix邮箱3、Gitlab优势4、Gitlab工作流程 三、Gitlab部署过程1、Yum安装Gitlab2、配置gitlab站点URL3、启动并访问Gitlab 四、Gitlab具体操作1、…

CSS盒子模型

盒子模型的组成 CSS会把所有的HTML元素都看成一个盒子&#xff0c;所有的样式也都是基于这个盒子 content&#xff08;内容&#xff09;&#xff1a;盒子的内容padding&#xff08;内边距&#xff09;&#xff1a;用于控制元素内部与边框之间的距离border&#xff08;边框&…

Qt打开及创建项目,运行程序(1)

安装之后&#xff0c; 1.文件->新建文件或项目 2.Application->Qt Widgets Application 3.自己设置名称和路径 4.这一步非常非常重要&#xff0c;要选择编译器&#xff0c;&#xff08;MinGW是可以在Qt里用&#xff0c;如果想与VS交互&#xff0c;要选择MSVC&#xff09…

去除pdf/word的水印艺术字

对于pdf中的水印如果无法去除水印&#xff0c;则先另存为word&#xff0c;然后再按下面办法处理即可&#xff1a; 查看宏&#xff0c;创建&#xff1a;删除艺术字 添加内容&#xff1a; Sub 删除艺术字()Dim sh As ShapeFor Each sh In ActiveDocument.ShapesIf sh.Type msoT…

如何使用谷歌浏览器连接linux服务器SSH服务

环境&#xff1a; 谷歌浏览器 版本 116.0.5845.141&#xff08;正式版本&#xff09; &#xff08;64 位&#xff09; Win10 专业版 安全外壳 (SSH)v.0.58 问题描述&#xff1a; 如何使用谷歌浏览器连接linux服务器SSH服务 解决方案&#xff1a; 1.找了有台安装好了这个插…

计算机视觉实战项目(图像分类+目标检测+目标跟踪+姿态识别+车道线识别+车牌识别)

图像分类 教程博客_传送门链接:链接 在本教程中&#xff0c;您将学习如何使用迁移学习训练卷积神经网络以进行图像分类。您可以在 cs231n 上阅读有关迁移学习的更多信息。 本文主要目的是教会你如何自己搭建分类模型&#xff0c;耐心看完&#xff0c;相信会有很大收获。废话不…

Vite+React+Electron开发入门,10分钟搭建本地环境并打包

前言 想使用vite和react开发跨平台桌面的软件方案有electron和tauri两种&#xff0c;但是我个人更喜欢tauri&#xff0c;无奈electron名声大燥&#xff0c;面试要求里很多都写着&#xff1a;electron...可见这类公司多么落后。但是呢&#xff0c;又秉持着存在即合理的理念&…

Ubuntu22.04开启后屏幕黄屏

1. 故障现象 系统&#xff1a;Ubuntu22.04 现象&#xff1a;电脑从开机到进入桌面一直屏幕黄屏 2. 故障分析 可能为屏幕色彩调节出现故障 3. 解决方案 系统设置——》色彩——》删除原来的配置&#xff08;remove profile&#xff09;——》添加配置Colorspace:Compatibl…

八股——const 关键字

1.const作用 作用&#xff1a;const用于保护指针指向数据不被修改 测试代码1 显示数组的函数不小心修改了指针指向的值&#xff0c;这时候没有加const关键字&#xff0c;编译器不会报错 #include <stdio.h> void showar(int ar[]);int main(void) {int ar[4]{2,3,4,5…

antd react 文件上传只允许上传一个文件且上传后隐藏上传按钮

antd react 文件上传只允许上传一个文件且上传后隐藏上传按钮 效果图代码解析 效果图 代码解析 import { Form, Upload, message } from antd; import { PlusOutlined } from ant-design/icons; import { useState, useEffect } from react; import { BASE_URL } from /utils/…

kafka增加磁盘或者分区,topic重分区

场景&#xff1a;kafka配置文件log.dirs增加了几个目录&#xff0c;但是新目录没有分区数据写入&#xff0c;所以打算进行重分区一下。 1.生成迁移计划 进入kafka/bin目录 新建 topic-reassign.json,把要重分区的topic按下面格式写。 { "topics": [{ …

深度学习基础之梯度下降

1. 引言 梯度下降是一种用于最小化&#xff08;或最大化&#xff09;损失函数的优化算法。它是机器学习和深度学习中的一个关键概念&#xff0c;通常用于调整学习算法中的参数。 梯度下降背后的核心思想是迭代调整参数以最小化损失函数。它的工作原理是计算损失函数相对于每个…

2023-09-12 LeetCode每日一题(课程表 IV)

2023-03-29每日一题 一、题目编号 1462. 课程表 IV二、题目链接 点击跳转到题目位置 三、题目描述 你总共需要上 numCourses 门课&#xff0c;课程编号依次为 0 到 numCourses-1 。你会得到一个数组 prerequisite &#xff0c;其中 prerequisites[i] [ai, bi] 表示如果你…

C基础-操作符详解

操作符分类&#xff1a; 算数操作符&#xff1a; - * / % //算数操作符 // int main() // { // // /除法 1.整数除法(除号两端都是整数) 2浮点数除法&#xff0c;除号的两端只要有一个小数就执行小数除法 // // 除法中&#xff0c;除数为0 // int a 7 / 2; /…