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

【汇编】思考汇编中的两个基本问题

1. 若干年前的疑问

几年前还在大学学习汇编时,不管是考试还是课程设计,其实都很顺利。但是心里一直对什么时候使用哪个寄存器存在疑惑,编写汇编时,没有十足的把握,都是抱着试一试的心态去完成了课程任务。

工作八年有余,已走在向linux内核进发的路上。在学习linux内核之前,心里存有一些侥幸,认为汇编可以跳过去。别人封装好,只管使用即可,反正自己又不一定写。在学习过程中,涉及到汇编的部分都是大致看一下设计思路。但是逐渐地,跳过的细节越来越多,导致书慢慢的越来越看不懂了。问题积少成多,窟窿越来越大,量变产生了质变。

汇编中的指令还是挺好理解的,就是一些功能函数,我相信大多数人理解起来问题都不大。

我认为汇编中最大的问题在于寄存器和内存的使用。CPU中寄存器的数量有限,引发了两个问题:

  1. 何时该用哪个寄存器
  2. 哪些数据存在寄存器哪些放在内存

这两个问题一直困扰着我,由于工作中用汇编比较少,所以这个问题一直没有得到深入地思考和解决。今天我们就尝试解决这两个汇编问题。

2. 汇编指令与高级语言中函数的相同点和不同点

我们直入主题,汇编指令与高级语言中函数的相同点是:

  • 汇编指令和函数一样,都是为了完成某个操作的功能单元,他们都有输入和输出,说白了,你可以把汇编指令也看成是一种函数。

不同点是:

  • 单个汇编指令不能嵌套调用,可以组合调用;成对搭配的汇编指令,可以嵌套调用,比如CALL和RET。
  • 单个函数可以嵌套调用,也可以组合调用

3. 单个指令的“独占性原理”

寄存器的个数是很有限的,但是指令确有很多很多,寄存器够用吗?

答案是,对单个指令来说,肯定是够用的。因为单个指令不能嵌套,所以我们可以确定,一个指令在被CPU核执行的时候,是“独占”所有它可以操作的寄存器的,因为此刻一个CPU核中不会有其他指令执行。这样一来,我们可以确定,对一条指令来说,寄存器虽然很少,但肯定是足够的。CPU厂家在设计指令时,不会设计使用超额寄存器数量的指令。

单条指令的“独占性原理”,保证了CPU中即使只有有限数量的寄存器,也能正确执行任何单个指令。

4. 多指令协同与优化

从单个指令执行过程看,单个指令执行有“独占性原理”。

从多个指令执行过程看,寄存器还能够用吗?设想一下,如果前一个指令执行后,有很多重要的数据存在于寄存器中保存,而当前的指令又需要独占寄存器,很有可能会把存在于寄存器中重要的数据给“覆盖”、“破坏”了,从而导致重要数据丢失。这种情形下,程序将无法正确执行。出现这种问题的根本原因还是在于寄存器数量有限,如果寄存器数量很多很多,那么只要合理分配和释放,数据就不会被覆盖。

所以,在多指令角度,因为寄存器数量有限,又出现了新的问题。怎么解决这个问题呢?

通过将下一条指令需要的数据留在寄存器中,将下一条指令不需要的数据放到内存中,这个问题迎刃而解。下一条指令需要的数据,其实就是指令的输入参数。前后指令配合的过程,我起个名字,叫“多指令协同”。

其实把下一条指令的输入参数留下,不需要的数据放入内存,是一种简单粗暴的做法。细想之下,如果寄存器数量还有空余,其实可以多留一些数据在寄存器中,给下下条指令,下n条指令传参,这样可以减少内存的访问,提高执行效率。但是这种预留是不确定的,是动态的,是具体的,必须根据具体的指令,使用的参数个数,返回值个数,进行专门优化。这个过程,我称之为“多指令协同优化”。

在编译高级语言的过程中,编译器会在生成汇编语言时,根据编译参数,自动进行优化。在编译程序时,不同的编译优化等级,优化的算法和力度是不同的。如果考虑上CPU的多级缓存,其实优化过程还是很复杂的。这里我们暂时不做深入研究。

5. 汇编编程套路

工作做到最后,都是套路。套路换一个词,就是经验。如何能够把汇编程序写得又快又好,那就需要学习套路。

我们上面说了,当写多条指令的时候需要注意优化寄存器和内存的使用。这个优化太自由了,你可以这么优化,我可以那么优化,自由的东西一定程度上,是没有标准没有把握的东西。我们平时写代码,如何更多的关注于业务呢?这里讲一种方法。

程序都是由一小块一小块功能模块的代码组成的,汇编也是一样。汇编程序是由很多汇编代码段组成的。这里用代码段来讲,而不是用函数来讲,是因为函数也有可能是由几个代码段组成。所以代码段是比函数更小的代码模块。

有了代码段的概念之后,我们可以把“指令独占性原理”,扩展到代码段,变成“汇编代码段独占性原理”。我们可以认为一个代码段执行过程中,独占所有寄存器,代码段执行完成后,可以通过某几个寄存器向接下来的代码段传递参数,剩下的寄存器,默认将成为空闲寄存器,里面的数据可以被覆盖。如果有的寄存器需要延长生命期,可以把寄存器中的数据保存到内存中,从而将寄存器释放出来。

这样,下一个代码段也将独占所有寄存器。这样就不用时刻担心,这个寄存器能不能用,会不会覆盖已有的数据了。

本质上,这是通过控制作用域与生命期,来调整软件架构的方法,这个方法在编程中很常用。

6. 结论

通过一步步推导“单指令独占性”原理,“多指令协同”,“多指令协同优化”,“汇编编程套路-代码段独占性原理”,可以很好的解答本文开始提出来的疑问。寄存器,内存的使用是有章可循的,大致的原则和方法要心中有数,才能算是对汇编有一定的掌握,编写或者阅读代码时,才能更有信心。

我的学习习惯就是这样,基本的思路逻辑必须先梳理清晰,而不是一头扎进细节里。重要的细节,我在后面的文章中会进行专门探讨。

相关文章:

【汇编】思考汇编中的两个基本问题

1. 若干年前的疑问 几年前还在大学学习汇编时,不管是考试还是课程设计,其实都很顺利。但是心里一直对什么时候使用哪个寄存器存在疑惑,编写汇编时,没有十足的把握,都是抱着试一试的心态去完成了课程任务。 工作八年有…...

开发环境服务器 vs 生产环境服务器:开发与生产须分明

【背景】作为开发者,我们在不同的阶段都与两种服务器环境打交道——开发环境服务器和生产环境服务器。虽然听起来名字相似,但它们的职责和工作方式简直是天差地别! 不知道朋友们有没有跟我一开始刚了解的时候的一些疑惑,因为刚开始…...

Tomcat的安装即使用

Tomcat的概念 Tomcat服务器是Java语言开发的,免费的开放源代码的Web应用服务器。 Tomcat处理静态HTML的能力远不及Apache或者Nginx,通常是作为一个Servlet和JSP容器,单独运行在后端。 Tomcat是由三个功能组合而成: java servlet&…...

外包干了9天,技术退步明显。。。。。

时光荏苒,转眼我已是一个拥有近四年功能测试经验的大专生。19年,我满怀激情地通过校招进入湖南某知名软件公司,期待在这里开启我的职业生涯。然而,长时间的舒适环境让我渐渐失去了前进的动力,技术停滞不前,…...

梳理你的思路(从OOP到架构设计)_基本OOP知识04

目录 1、 主动型 vs.基於被动型 API 1)卡榫函数实现API 2)API的分类 3)回顾历史 4)API >控制力 2、 结语&复习: 接口与类 1)接口的表示 2)Java的接口表示 1、 主动型 vs.基於被动…...

每天40分玩转Django:简介和环境搭建

Django简介和环境搭建 一、课程概述 学习项目具体内容预计用时Django概念Django框架介绍、MVC/MTV模式、Django特点60分钟环境搭建Python安装、pip配置、Django安装、IDE选择45分钟创建项目项目结构、基本配置、运行测试75分钟实战练习创建个人博客项目框架60分钟 二、Djang…...

OpenCV相关函数

一、Sobel算子函数 (cv2.Sobel) 功能 Sobel算子是一个梯度算子,用于边缘检测。通过计算图像中像素的梯度,Sobel算子可以检测出水平和垂直方向上的边缘。 参数 src:输入图像。 ddepth:输出图像的深度(如cv2.CV_8U, cv…...

【理想汽车中科院】基于模仿学习的端到端自动驾驶数据缩放规律

论文: https://arxiv.org/pdf/2412.02689 项目: https://github.com/ucaszyp/Driving-Scaling-Law 0. 摘要 端到端自动驾驶范式因其可扩展性而最近吸引了大量关注。然而,现有方法受到现实世界数据规模有限的制约,这阻碍了对端到端自动驾驶相关扩展规律…...

重卡补能新未来:光储充换一体开启高效之路

《重卡补能新未来:光储充换一体开启高效之路》 一、光储充换一体重卡补能模式的兴起 重卡运输行业在电动化进程加速下迎来变革,光储超充快换一体化补能站成为新趋势。 随着国家 “双碳” 战略的持续推进,新能源汽车市场蓬勃发展&#xff0c…...

Mybatis Plus 3.0 快速入门

1、简介 MyBatis-Plus (简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。 2、创建并初始化数据库 2.1、创建数据库 mybatis_plus 2.2、创建 User 表 其表结构如下: idnameageemail1Jone18test1@baomidou.com2Jack…...

ABAP:MB51字段增强

MB51所对应的程序:RM07DOCS 1.定义增强字段:RM07DOCS_GENERATED中定义 2.取值:RM07DOCS中detail_list中加取值逻辑 也有对ITAB取值做调整的,但是要写很多处,直接这里取值就很简单。 3.展示字段:RM07DOCS中…...

nVisual 定制化APP打包流程

一、下载打包软件 HBuilder X 下载地址:https://dcloud.io/hbuilderx.html 安装:此软件为绿色软件,解压即可使用。进入目录,双击exe启动。 此软件需要注册,打开时会提供跳转链接,通过邮箱注册账号。 注册成功后&#…...

k8s的节点亲和性NodeAffinity

关键词: ① requiredDuringSchedulingIgnoredDuringExecution:表示强匹配,必须要满足 ② preferredDuringSchedulingIgnoredDuringExecution:表示弱匹配,尽可能满足,但不保证 示例: apiVersion: v1 kind:…...

比特币国家与企业机构“战略储备”潮起

100 万枚 BTC 的战略储备资产,是一个什么概念? 据世界黄金协会统计数据显示,截至 2024 年第三季度,美联储黄金储备总量达 8133.46 吨(约合 5300 亿美元),稳居全球首位。而 100 万枚 BTC 当前市…...

Vue生命周期钩子函数:深入解析与实践

作为高级Vue前端开发人员,对Vue组件的生命周期钩子函数有着深刻的理解是至关重要的。生命周期钩子函数是指在Vue组件的创建、更新、销毁等过程中,Vue自动调用的一系列方法。通过这些钩子函数,我们可以在组件的不同生命周期阶段执行特定的操作…...

mysql、postgresql、oceanbase调优

一、mysql 1、my.cnf [mysqld_safe] log-error=/data/mysql/log/mysql.log pid-file=/data/mysql/run/mysqld.pid[client] socket=/data/mysql/run/mysql.sock default-character-set=utf8[mysqld] basedir=/usr/local/mysql tmpdir=/data/mysql/tmp datadir=/data/mysql/dat…...

【Flux.jl】 卷积神经网络

Flux.jl 是包含卷积神经网络的, 但是官方API文件中没有给出一个完整的程序框架, 只是对所需神经元给了局部解释, 此外对 model-zoo 模型动物园中的案例没有及时跟着 Flux.jl 的版本更新, 也无法运行出来结果。 因此本文搭建了一个完整可训练的卷积神经网络。 Conv 卷积算子…...

数字证书管理工具 openssl keytool

OPENSSL 命令 openssl command [ command_opts ] [ command_args ] 常用command: version 用于查看版本信息 enc 用于加解密 ciphers 列出加密套件 genrsa 用于生成私钥 -des|-des3|-idea:用来加密私钥文件的三种对称加密算法。 rsa …...

notify和notifyAll

notify和notifyAll 简单来说: notify():只唤醒一个等待的线程,如果有多个线程在等待,那么被唤醒的线程是随机选择的。 notifyAll():唤醒在该对象监视器上等待的所有线程,但是这些被唤醒的线程仍然需要竞争…...

删除MySQL的多余实例步骤

删除 MySQL 的多余实例通常意味着我们希望卸载或停止某个 MySQL 服务器实例,并从系统中完全移除它。这通常涉及到几个步骤,包括但不限于停止服务、删除数据目录、卸载软件(如果适用)等。 1.基于 Linux 的系统上删除 MySQL 的多余…...

LDR6500应用:C转DP线材双向投屏开启全新体验

在当今这个科技日新月异、蓬勃发展的时代,高清视频传输以及显示技术已经深深融入到我们日常生活与工作的方方面面,其重要性不言而喻。不管是在商务场合的会议演示,还是教育领域的娱乐享受,以及充满激情的游戏竞技领域,…...

商业化大前端在性能优化领域的探索与实践

导读:在业务飞速发展的过程中,用户体验是必不可少的一个环节,而页面性能是直接影响用户体验的重要因素。当页面加载时间过长、交互操作不流畅时,意味着业务可能会出现转化率降低、用户流失等业务问题。在过去一年,为了…...

FinClip | 2024年11月产品大事记

FinClip 的使命是使您(业务专家和开发人员)能够通过小程序解决关键业务流程挑战,并完成数字化转型的相关操作。不妨让我们看看在11月的产品与市场发布亮点,看看是否有助于您实现目标。 产品方面的相关动向👇&#x1f…...

EasyPlayer.js在同一个http的mp4视频流地址,浏览器可以播放,播放器中却播放不了

流媒体技术正站在数字化时代的前沿,随着互联网技术的不断进步和市场需求的日益增长,其发展前景显得尤为广阔。随着全球数字化转型的不断深入,流媒体行业将迎来更加繁荣的未来,成为信息传播和娱乐消费的主要渠道。 用户遇到在同一个…...

探索云原生安全解决方案的未来

我们是否充分意识到云端所面临的网络安全威胁? 在当今互联互通的世界中,维护安全的环境至关重要。云的出现扩大了潜在威胁的范围,因为它催生了机器身份(称为非人类身份 (NHI))及其秘密。随着组织越来越多地转向云原生…...

发愿和许愿的区别是什么?

在许多宗教和文化中,发愿和许愿都是人们表达内心愿望、祈求神灵保佑的重要方式。尽管这两个词在日常生活中经常被交替使用,但它们在含义和实践上存在一些重要的区别。本文就来详细说说发愿和许愿的区别,并提供相关的背景信息和建议。 1. 定义…...

【IntelliJ IDEA 集成工具】TalkX - AI编程助手

前言 在数字化时代,技术的迅猛发展给软件开发者带来了更多的挑战和机遇。为了提高技术开发群体在繁多项目中的编码效率和质量,他们需要一个强大而专业的工具来辅助开发过程,而正是为了满足这一需求,TalkX 应运而生。 一、概述 1…...

【故障处理--修改CI流水线】

背景:研发同事反映CI流水线卡顿严重,判断是移动云镜像仓库的带宽太小,故在公有云搭建一个harbor仓库,这就意味着CI流水线有些配置需要改动 1、CI流水线的介绍 helm-chart/pcas-appstore-hy存放的是chart包需要的文件 Dockerfile…...

Android 使用 Gson + OkHttp 实现 API 的常规使用(个人心得)

学习笔记 一、依赖和权限的添加 网络权限: 在 Android 中进行网络请求时,必须声明权限,确保应用具有访问互联网的能力。 <uses-permission android:name="android.permission.INTERNET"/> 依赖项: 确保在 build.gradle 中添加以下依赖: dependencies …...

MR30分布式 IO 模块:硅晶行业电池片导片机的智能 “心脏”

硅晶产业作为全球能源和电子领域的基石&#xff0c;其生产规模庞大且工艺复杂。从硅料的提纯、拉晶&#xff0c;到硅片的切割、电池片的制造&#xff0c;每一个环节都要求高精度与高稳定性。在电池片生产环节&#xff0c;导片机承担着硅片传输与定位的重要任务&#xff0c;其运…...

mysql高级篇 | 尚硅谷 | 第2章_数据库和文件系统的关系

二、数据库和文件系统的关系 文章目录 二、数据库和文件系统的关系1、查看默认数据库2、 数据库在文件系统中的表示3、表在文件系统中的表示①InnoDB存储引擎模式②表中数据和索引②MyISAM存储引擎模式 4、小结 1、查看默认数据库 查看一下在我的计算机上当前有哪些数据库&…...

React 生命周期

React 生命周期可以分为三个主要阶段&#xff1a;挂载&#xff08;Mounting&#xff09;、更新&#xff08;Updating&#xff09;和卸载&#xff08;Unmounting&#xff09; 挂载&#xff08;Mounting&#xff09; 当组件实例被创建并插入到 DOM 中时&#xff0c;会依次调用以…...

OpenCV--图像查找

OpenCV--图像查找 代码和笔记 代码和笔记 import cv2 import numpy as np""" 图像查找--特征匹配的应用&#xff0c;通过特征匹配和单应性矩阵 单应性变换&#xff1a;描述物体在世界坐标系&#xff08;原图&#xff09;和像素坐标系&#xff08;对比图&#x…...

数据保护策略:如何保障重要信息的安全

一、什么是数据安全&#xff1f; 数据安全是保护数字信息免遭盗窃、未经授权的访问和恶意修改的过程。这是一个持续的过程&#xff0c;负责监督信息的收集、存储和传输。 机密性&#xff1a;保护数据免遭未授权方访问。 完整性&#xff1a;保护数据免遭未经授权的修改、损坏…...

AI生成图表化:深入探索Mermaid

引言 在使用生成式AI时&#xff0c;只要你提出让AI帮你生成mermaid图&#xff0c;AI的生成就会出现丰富的图形&#xff01; 在现代文档编写中&#xff0c;图表的使用不仅能增强文档的可读性&#xff0c;还能更直观地表达复杂的概念和流程。Mermaid 作为一款开源的图表绘制工具…...

模型训练中梯度累积步数(gradient_accumulation_steps)的作用

模型训练中梯度累积步数&#xff08;gradient_accumulation_steps&#xff09;的作用 flyfish 在使用训练大模型时&#xff0c;TrainingArguments有一个参数梯度累积步数&#xff08;gradient_accumulation_steps&#xff09; from transformers import TrainingArguments梯…...

jenkins安装(jdk1.8已安装)

1. 下载对应jenkins版本 https://mirrors.jenkins.io/war/ 2. 上传至服务器目录并启动 mkdir -p /root/jenkins cd /root/jenkins 上传文件 启动&#xff1a;nohup java -jar jenkins.war --httpPort9090 &> jenkins.log & 访问&#xff1a;http://ip:9090 选…...

爬虫实战:获取1688接口数据全攻略

引言 在电商领域&#xff0c;数据的重要性不言而喻。1688作为中国领先的B2B电商平台&#xff0c;提供了海量的商品数据。通过爬虫技术获取这些数据&#xff0c;可以帮助企业进行市场分析、价格监控和供应链管理。本文将详细介绍如何使用Python爬虫技术合法合规地获取1688接口数…...

基于Mybatis,MybatisPlus实现数据库查询分页功能

基于Mybatis&#xff0c;MybatisPlus实现数据库查询分页功能 目录 基于Mybatis&#xff0c;MybatisPlus实现数据库查询分页功能使用Mybatis插件实现分页数据库准备分页插件配置和使用常用数据&#xff1a; 使用MybatisPlus插件实现分页数据库准备分页插件配置和使用自定义分页查…...

【C++】求第二大的数详细解析

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;题目描述&#x1f4af;输入描述&#x1f4af;解题思路分析1. 题目核心要求2. 代码实现与解析3. 核心逻辑逐步解析定义并初始化变量遍历并处理输入数据更新最大值与次大值输…...

Ubuntu18安装后基本配置操作

1. 关掉自动更新 不关掉自动更新&#xff0c;会将你的ubuntu系统更新到更高版本&#xff0c;一些配置就不能用了&#xff0c;所以要关掉自动更新。在“软件和更新”中将“自动检查更新”设置为从不。 2. ubuntu换国内源 参考链接换源 按照这个换源这个换源好使 &#xff0c;…...

【Azure 架构师学习笔记】- Azure Function (1) --环境搭建和背景介绍

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Function 】系列。 前言 随着无服务计算的兴起和大数据环境中的数据集成需求&#xff0c; 需要使用某些轻量级的服务&#xff0c;来实现一些简单操作。因此Azure Function就成了微软云上的一个必不可少的组成部分。 …...

【ubuntu】将Chroma配置为LINUX服务

Chroma是一个轻量级向量数据库。既然是数据库&#xff0c;那么我希望它是能够长时间运行。最直接的方式是配置为service服务。 可惜官方没有去提供配置为服务的办法&#xff0c;而鄙人对docker又不是特别感冒。所以自己研究了下chroma配置为服务的方式。 系统&#xff1a;ubu…...

Linux24.04 安装企业微信

今天工作需要把windows系统换成了linux&#xff0c;但是公司的沟通工具是企业微信。去企业微信官网看了&#xff0c;没有linux版本&#xff0c;只能想办法解决了&#xff0c;不然再换回去就太坑了。 方案 1、使用docker容器&#xff0c;2、使用deepin-wine 本人对docker不太熟…...

路由引入问题(双点双向路由回馈问题)

简介 总所周知&#xff0c;路由引入import又称路由重分发redistribute&#xff0c;为了解决不同路由协议进程间路由信息不互通而使用的技术&#xff0c;由于不同路由协议的算法、机制、开销等因素的差异&#xff0c;它们之间无法直接交换路由信息。因此&#xff0c;路由引入技…...

Redis 实现分布式锁

单实例条件下的分布式锁 -- 加锁操作 -- KEYS[1]: 锁的键&#xff08;lock_key&#xff09; -- ARGV[1]: 当前客户端的标识&#xff08;client_id&#xff09; -- ARGV[2]: 锁的过期时间&#xff08;毫秒&#xff09;if (redis.call(EXISTS, KEYS[1]) 0) then-- 如果锁不存在…...

Redis客户端(Jedis、RedisTemplate、Redisson)

1. 简介 Redis作为一个当下很火热的非关系型数据库&#xff0c;Java从业人员基本都离不开对Redis的使用。在Java程序中该数据库&#xff0c;需要借助于市面上的开源客户端&#xff0c;如Jedis、Spring Data Redis、Redisson&#xff0c;它们可以作为操作Redis非关系型数据库的桥…...

虚幻引擎内各个组件的关系

1. GameMode: 关系: GameMode 是游戏规则的制定者和管理者,GameState 则是游戏状态的记录者和同步者。GameMode 通常负责创建和初始化 GameState。 交互: GameMode 可以直接访问和修改 GameState 的属性,例如更新游戏分数、切换游戏阶段等。GameState 的变化会通过 GameMode …...

Python Flask Web框架快速入门

Flask 入门Demo Flask 开发环境搭建&#xff0c;执行如下指令&#xff1a; pip install flask# 第一节: Flask 快速入门from flask import Flask app Flask(__name__)app.route(/flask) def hello_flask():return Hello Flaskapp.run()核心代码剖析&#xff1a; 从flask包导…...

【java学习笔记】Set接口实现类-LinkedHashSet

一、LinkedHashSet的全面说明 &#xff08;就是把数组不同位置的链表当成一个节点然后相连&#xff09;...