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

从汇编看函数调用

文章目录

    • 函数调用流程
    • 栈相关寄存器及的作用简介
      • 寄存器功能
      • 指令功能
    • 函数的括号{}
      • 正括号
      • 反括号
    • 参数传递
        • 传值,变量不可改
        • 传指针,变量可改
        • C++ 传引用
    • 函数调用实例

函数调用流程

目标:函数调用前后栈保持不变
在这里插入图片描述

  1. 保存main函数的寄存器上下文
  2. 移动栈指针,到新栈
  3. 调用新函数:新函数会开辟内存然后操作
  4. 恢复栈指针

栈相关寄存器及的作用简介

寄存器功能

在这里插入图片描述ESP/RSP:堆栈指针寄存器,指向栈顶。栈顶指针
EBP/RBP:栈底指针,指向栈的底部,通常用ebp+偏移量的形式来定位函数存放在栈中的局部变量

rax:通常用于存储函数调用返回值
rdi:第一个入参
rsi:第二个入参
rdx:第三个入参
rcx:第四个入参
r8:第五个入参
r9:第六个入参

寄存器ebp作为当前函数的“栈帧”基地址,配合一定的偏移,就可以读、写函数体的临时变量。如果一个变量是通过ebp寄存器间接访问的,那么它往往是临时变量,也叫“栈”变量。

指令功能

在这里插入图片描述
在这里插入图片描述

push rbp 保存上下文,保存rbp值
1.rbp里面的值放到当前rsp指向的位置,保存当前栈底指针的值
2. 然后rsp–,栈顶指针向上移动

pop eax 恢复栈帧
1. 栈顶指针向下移动,这里的值保存的是原函数的栈底位置
2. ebp指向esp里面值的位置,移动栈底指针到原函数位置

在这里插入图片描述
call
1. 会把call指令的下一条指令压入栈,把下一条指令的地址,也就是函数func的返回地址(0x401105e)压入堆栈
2.CPU跳转到函数func的首地址。
在这里插入图片描述在这里插入图片描述

栈是存储临时数据的区域,在普通内存中,它的特点是通过push指令和pop指令进行数据的存储和读出。往栈中存储数据称为“入栈”,从栈中读出数据称为“出栈”。32位x86系列的CPU中,进行1次push或pop,即可处理32位(4字节)的数据。push指令和pop指令中只有一个操作数。该操作数表示的是“push的是什么及pop的是什么”,而不需要指定“对哪一个地址编号的内存进行push或pop”。
这是因为,对栈进行读写的内存地址是由esp寄存器(栈指针)进行管理的。push指令和pop指令运行后,esp寄存器的值会自动进行更新(push指令是-4, pop命令是+4),因而程序员就没有必要指定内存地址了。

栈是由大地址向小地址递减,而堆和普通内存是小地址到大地址递增

操作系统会为每个任务(进程或线程)分配一段内存当作任务“堆栈”;CPU则提供两个寄存器esp、ebp,用来标识当前函数对“堆栈”的使用情况。随着函数的逐层调用,函数的“栈帧”会逐次堆叠,互不重合;随着函数的逐层返回,函数的“栈帧”会被就地放弃,但不会清理内存

函数的括号{}

其实函数的调用主要部分就是正反括号的内容
正负括号都对应两条指令。
在这里插入图片描述

正括号

先看正括号,三条指令,作用是保存原栈,并分配新的栈空间

  1. push rbp : push指令把寄存器ebp的值压入“栈顶”,然后将“栈顶”红色水位线(CPU寄存器esp)上移,扩大栈空间。至此,main函数的“栈帧”保护工作完成!
  2. 然后通过mov指令,更新一下“栈帧”基准线,让ebp指向esp,这里就是新的func的栈了
    在这里插入图片描述

反括号

然后看反括号两条指令:反括号作用是恢复栈

  1. pop, 把事先压入“栈顶”的ebp值返还给CPU寄存器ebp。这样蓝色基准线就恢复到了最开始的位置。然后esp红色水位线也随之下降。esp和ebp的值就都恢复了。
  2. ret指令,把“栈顶”处的返回值传给CPU寄存器rip,这样,CPU就可以跳转到主调函数main被打断的地方0x401105e继续执行了。

参数传递

先看下传递参数的汇编:
在这里插入图片描述

  1. 传值调用和传指针其实都是将值传递到函数中,只不过这个值含义不同指针是一个地址的值。
  2. 还可以看出用作传参的寄存器是哪几个。
传值,变量不可改

我们接着看函数中,对参数赋值的汇编:
在这里插入图片描述1. 这里会将参数寄存器中的值,放入栈中。然后释放参数寄存器。
2. 然后将内存地址数据赋值。
3. 这也就说明原来参数的值被复制了一份到内存中,修改当前形参的值,实际是修改栈中内存的值,原变量不会被修改

传指针,变量可改

在这里插入图片描述

  1. 首先还是将参数的值放入内存中,释放寄存器
  2. 然后将参数x的内存地址传给寄存器,寄存器当前存储的是该地址
  3. 然后向该寄存器中存储的地址中,写入0.
    这也就直接修改了内存中原变量的值,这里的寄存器rax起到了一个中间过渡作用。

Q:为什么传递参数是通过CPU寄存器,而不是直接压入堆栈呢?
A:传递参数,也可以不通过CPU寄存器,而通过压入堆栈的方式,一些老版本的编译器,也是如此操作的。但通过寄存器传递,可以避免一些内存操作,一定程度上有利于提高函数的执行效率。

C++ 传引用

C++ 传引用和传指针的汇编相同,所以传引用只是一个语法糖
在这里插入图片描述

函数调用实例

在这里插入图片描述

相关文章:

从汇编看函数调用

文章目录 函数调用流程栈相关寄存器及的作用简介寄存器功能指令功能 栈函数的括号{}正括号反括号 参数传递传值,变量不可改传指针,变量可改C 传引用 函数调用实例 函数调用流程 目标:函数调用前后栈保持不变 保存main函数的寄存器上下文移…...

node.js的错误处理

当我打开一个不存在的文件时,错误如下: 在读取文件里面写入console.log(err),在控制台中可以看到我的错误代码类型:文件不存在的错误代码 ENOENT。见更多错误代码---打开node.js官方API文档Error 错误 | N…...

shell的编写

文章目录 1.框架2.命令行3.获取用户命令字符串4.命令行字符串分割5.执行命令和内建命令6.完整代码: 1.框架 我们知道shell是一直存在的,所以首先我们第一步就是要搭建一个框架,使其一直存在。 那么也很简单,一个while循环就可以完…...

css心跳动画

图标引入 <img class"icon" src"heart.svg" alt"" srcset""> CSS代码 <style>.icon {animation:bpm 1s linear,pulse 0.75s 1s linear infinite;}keyframes pulse {from,75%,to {transform: scale(1);}25% {transform:…...

在 Amazon Timestream 上通过时序数据机器学习进行预测分析

由于不断变化的需求和现代化基础设施的动态性质&#xff0c;为大型应用程序规划容量可能会非常困难。例如&#xff0c;传统的反应式方法依赖于某些 DevOps 指标&#xff08;如 CPU 和内存&#xff09;的静态阈值&#xff0c;而这些指标在这样的环境中并不足以解决问题。在这篇文…...

【智能排班系统】快速消费线程池

文章目录 线程池介绍线程池核心参数核心线程数&#xff08;Core Pool Size&#xff09;最大线程数&#xff08;Maximum Pool Size&#xff09;队列&#xff08;Queue&#xff09;线程空闲超时时间&#xff08;KeepAliveTime&#xff09;拒绝策略&#xff08;RejectedExecutionH…...

C语言——内存函数

前言&#xff1a; C语言中除了字符串函数和字符函数外&#xff0c;还有一些函数可以直接对内存进行操作&#xff0c;这些函数被称为内存函数&#xff0c;这些函数与字符串函数都属于<string.h>这个头文件中。 一.memcpy&#xff08;&#xff09;函数 memcpy是C语言中的…...

ideaSSM图书借阅管理系统VS开发mysql数据库web结构java编程计算机网页源码maven项目

一、源码特点 SSM 图书借阅管理系统是一套完善的信息管理系统&#xff0c;结合SSM框架和bootstrap完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用SSM框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统具有完整的源代码 和数据库&#xff0c;系统主…...

普联一面4.2面试记录

普联一面4.2面试记录 文章目录 普联一面4.2面试记录1.jdk和jre的区别2.java的容器有哪些3.list set map的区别4.get和post的区别5.哪个更安全6.java哪些集合类是线程安全的7.创建线程有哪几种方式8.线程的状态有哪几种9.线程的run和start的区别10.什么是java序列化11.redis的优…...

SQLite的架构(十一)

返回&#xff1a;SQLite—系列文章目录 上一篇&#xff1a;SQLite下一代查询规划器(十&#xff09; 下一篇&#xff1a;SQLite—系列文章目录 介绍 本文档介绍SQLite库的架构。 这里的信息对那些想要了解或 修改SQLite的内部工作原理。 接口SQL 命令处理器虚拟机B-树…...

Vue2电商前台项目(一):项目前的初始化及搭建

一、项目初始化 创建项目&#xff1a;sudo vue create app 1.项目配置 &#xff08;1&#xff09;浏览器自动打开 在package.json文件中&#xff0c;serve后面加上 --open "scripts": {"serve": "vue-cli-service serve --open","buil…...

4.6 offset指令,jmp short指令,far,dword ptr各种跳转指令

4.6 offset指令&#xff0c;jmp short指令&#xff0c;far&#xff0c;dword ptr各种跳转指令 可以修改IP&#xff0c;或同时修改CS和IP的指令统称为转移指令。概括的讲&#xff0c;转移指令就是可以控制CPU执行内存中某处代码的指令 1. 转移指令 1.1 8086CPU的转移行为有以…...

【WEEK5】 【DAY5】DML语言【中文版】

2024.3.29 Friday 目录 3.DML语言3.1.外键&#xff08;了解&#xff09;3.1.1.概念3.1.2.作用3.1.3.添加&#xff08;书写&#xff09;外键的几种方法3.1.3.1.创建表时直接在主动引用的表里写&#xff08;被引用的表的被引用的部分&#xff09;3.1.3.2.先创建表后修改表以添加…...

媒体偏见从何而来?--- 美国MRC(媒体评级委员会)为何而生?

每天当我们打开淘宝&#xff0c;京东&#xff0c;步入超市&#xff0c;逛街或者逛展会&#xff0c;各种广告铺天盖地而来。从原来的平面广告&#xff0c;到多媒体广告&#xff0c;到今天融合AR和VR技术的数字广告&#xff0c;还有元宇宙虚拟世界&#xff0c;还有大模型加持的智…...

Solana 线下活动回顾|多方创新实践,引领 Solana“文艺复兴”新浪潮

Solana 作为在过去一年里实现突破式飞跃的头部公链&#xff0c;究竟是如何与 Web3 行业共振&#xff0c;带来全新的技术发展与生态亮点的呢&#xff1f;在 3 月 24 日刚结束的「TinTin Destination Moon」活动现场&#xff0c;来自 Solana 生态的的专家大咖和 Web3 行业的资深人…...

CSS3 实现文本与图片横向无限滚动动画

文章目录 1. 实现效果2.html结构3. css代码 1. 实现效果 gif录屏比较卡&#xff0c;实际很湿滑&#xff0c;因为是css动画实现的 2.html结构 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"…...

Android 性能优化之黑科技开道(一)

1. 缘起 在开发电视版智家 App9.0 项目的时候&#xff0c;发现了一个性能问题。电视系统原本剩余的可用资源就少&#xff0c;而随着 9.0 功能的进一步增多&#xff0c;特别是门铃、门锁、多路视频同屏监控后等功能的增加&#xff0c;开始出现了卡顿情况。 经过调研分析发现有…...

Successive Convex Approximation算法的学习笔记

文章目录 一、代码debug二、原理 本文主要参考了CSDN上的 另一篇文章&#xff0c;但规范了公式的推导过程和修缮了部分代码 一、代码debug 首先&#xff0c;我们将所有的代码放到MATLAB中&#xff0c;很快在命令行中出现了错误信息 很显然有问题&#xff0c;但是我不知道发生…...

IoT数采平台2:文档

IoT数采平台1&#xff1a;开篇IoT数采平台2&#xff1a;文档IoT数采平台3&#xff1a;功能IoT数采平台4&#xff1a;测试 【平台功能】 基础配置、 实时监控、 规则引擎、 告警列表、 系统配置 消息通知&#xff1a;Websocket 设备上线、设备下线、 数据变化、 告警信息、 实时…...

Vue监听器watch的基本用法

文章目录 1. 作用2. 格式3. 示例3.1 value 值为字符串3.2 value 值为函数3.3 value 值为对象 4. 与计算属性对比 1. 作用 监视数据变化&#xff0c;执行一些业务逻辑或异步操作。 2. 格式 监听器 watch 内部以 key &#xff1a;value 的形式定义&#xff0c;key 是 data 中的…...

day52 ResNet18 CBAM

在深度学习的旅程中&#xff0c;我们不断探索如何提升模型的性能。今天&#xff0c;我将分享我在 ResNet18 模型中插入 CBAM&#xff08;Convolutional Block Attention Module&#xff09;模块&#xff0c;并采用分阶段微调策略的实践过程。通过这个过程&#xff0c;我不仅提升…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…...

MySQL账号权限管理指南:安全创建账户与精细授权技巧

在MySQL数据库管理中&#xff0c;合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号&#xff1f; 最小权限原则&#xf…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

Golang——9、反射和文件操作

反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一&#xff1a;使用Read()读取文件2.3、方式二&#xff1a;bufio读取文件2.4、方式三&#xff1a;os.ReadFile读取2.5、写…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能

1. 开发环境准备 ​​安装DevEco Studio 3.1​​&#xff1a; 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK ​​项目配置​​&#xff1a; // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

MySQL 主从同步异常处理

阅读原文&#xff1a;https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主&#xff0c;遇到的这个错误&#xff1a; Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一&#xff0c;通常表示&#xff…...

LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用

中达瑞和自2005年成立以来&#xff0c;一直在光谱成像领域深度钻研和发展&#xff0c;始终致力于研发高性能、高可靠性的光谱成像相机&#xff0c;为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...