2024王道考研计算机组成原理——指令系统
零、本章概要
指令寻址:解决的是PC+"1"的问题
数据寻址:使用寄存器/内存/结合
基址寻址:用于多道程序的并发执行
直接寻址:call 0x12345678
变址寻址:esi edi用于循环,因为使用直接寻址需要一堆地址很麻烦,速度也慢
相对寻址:地址针对的是相对于PC的位置,在代码位置发生改变的情况下用于实现跳转
PSW就是EFLAGS
x86汇编:
使用cmp+jnz(等)实现跳转指令;cmp会修改PSW的内容,jnz指令执行的适合会根据psw来判断需不需要跳转
循环语句:for(int i=0;i<10;i++){s+=arr[i];}:i++后面紧跟cmp
函数调用底层实现:
堆栈平衡:函数调用前后esp和ebp的位置不变,一个线程内的所有函数共用一个堆栈
x86的push和pop默认是按照4字节压栈/出栈的
esp指向的是栈顶的位置(有元素)
push eax:①先sub esp,4 ②再mov [esp],eax
pop eax:①先mov eax,[esp] ②再add esp,4
call eax:①push eip ②jmp eax
ret:pop eip(默认是ret 4)
真实的函数堆栈以及函数调用(见C语言函数调用的汇编视角)
CICS和RISC指令集的对比
一、指令格式

操作码:做什么 地址码:对谁做
当然停机指令特殊,不需要地址码,就是执行一个特殊的命令而已
Intel的CPU使用的是x86架构,x86架构的指令集和AMD的指令集是不兼容的,不能跨不同指令系统的机器执行,苹果公司宣布要抛弃Intel的CPU,转而开发自己的基于ARM架构的CPU,这样手机和电脑就能通用了

了解即可:
堆栈型计算机通过零地址指令来进行算术运算:操作数是隐藏在栈里面的,而不会显示地在栈中指明,扫描到操作符就相当于扫描到了一个零地址指令,会把操作数计算/弹出堆栈

所有指令访存次数都要加上取指令的那一次




注意:指令字长的长度是可变的(但是得是比如1B的整数倍),机器字长和存储字长都是不可变的
如果指令字长超过机器字长的话就需要多次的取指令操作,CPU可以根据操作码的类型来判断



我们所有的指令都是遵循操作码+地址码这种格式,只是地址码有可能为0,只有操作码这种情况出现,表示仅执行一次特殊的操作

二、扩展操作码指令格式
操作码全1用于区分是几地址指令
这里重点讨论的是n位操作码,能表示2^n种对于3/2/1地址的操作

三地址:15条0000-1110 A1 A2 A3
二地址(12条):1111 0000-1011 A1 A2
一地址(62条):1111 11 000000-111101 A1
零地址(32条):1111 11 11111 00000-11111
cpu分析指令的时候就根据前几位是1来判断他是几地址指令


三、指令寻址

PC+“1”
指令系统采用定长指令字结构: 定长指令+可变长操作码
因为每一条指令的长度是确定的,所以+"1"即可处理下一条指令

指令执行的时候先读入一个字
这里我想给大家重点讲解一下!!!!!!!!!!!!!!!!!!!!!!!
你CPU不是要从内存当中取指令吗?因为CPU一次最多只能同时处理一个字的数据,你就直接去指令所在的内存单元(在PC里存放地址)去取出一个字的内容,但是啊这一个字不是都有效啊!我CPU处理第一个字节的时候发现是55,后面直接扔掉就是了,然后根据55我就能知道这条指令的长度了,也就能知道PC应该加几了!然后可以继续去取下一条地址了!!!!!!!!



四、数据寻址

根据寻址特征和形式地址可以确定操作数的真实地址(EA)

了解即可,不用看:
立即寻址:立即数#010
直接寻址:call 0x12345678
间接寻址:lea [0x123456],地址放在某个内存单元里面
寄存器寻址:push ebp;mov eax,ecx
寄存器间接寻址:push [eax+4]

基址寻址就是用于多道程序并发执行的



直接寻址的bug:要用一堆地址

如何解决? esi edi就是变址寄存器,用于实现循环:rep stosw

直接寻址:地址是几就是几,你位置移动也是跳到2那里
(如何解决这个问题?)

你移动代码对顺序执行的指令没啥影响,但是跳转指令难绷啊😂😂😂
所以只要修改跳转指令的解释方式:因为PC会自动+1,所以使用-4(补码)来指示当前的CPU情况下应该跳转到哪里去执行
转移指令使用的都是相对寻址!!!

基址寻址:整个代码在内存当中的浮动;相对寻址:一段代码在程序内部的浮动

比较(相减)和跳转是分开的
PSW就是我们熟悉的ELAPGS

五、x86汇编语言基础
指令格式是什么样的取决于你的CPU,硬编码就是指令集里面的指令
55就是opcode,66就是前缀,CPU根据值来判断
55为啥是push ebp而不是push bp和当前CPU的模式有关,x86的保护模式默认是32位
前缀指令分成4个组,每个组有n个最多出现一个
定长指令:opcode确定了,指令的长度就确定了
变长指令:即使opcode确定了,指令的长度依然无法确定
opcode决定了有没有ModR/M,也决定了是不是定长指令
比如opcode是88那它后面一定根一个opcode


地址偏移和立即数

比如这种考题:

为啥x86汇编语言不允许两个操作数都同时来自主存?
1、指令长度太长了
2、访问2次主存太慢了吧。。。



x86:intel的8086/80286 80386
一条指令由操作码和若干地址码组成

进行除法运算的时候要对被除数进行位扩展:32->64(edx:eax) ,商存入eax,余数存入edx


intel格式(Windows)&AT&T(Linux&Unix)格式(汇编格式)


六、C语言选择语句的汇编实现
在x86当中IP就是PC
和前面提到的一样,我们这样写汇编代码,但是其实最后变成机器码的时候他会给我们翻译成与PC有关的指令,这样代码段即使移动位置,当PC指向这条语句的时候也能够跳转到正确的地址(使用PC+一个补码)

使用标号可以更方便程序员去编写汇编代码,最后编译器要做的就是把这个标号改成对于的地址

条件转移指令通常与cmp指令配合食用🤣🤣🤣

switch语句:离散情况不生成大表和if...else效率一样,连续的时候生成大表,先比较数值-1超过第二大的数就直接跳到default,否则直接根据edx*4+func(函数首地址) 来去查大表,直接得到跳转地址而不用像if..else那样进行多次的比较!!!
只有特定的指令(比如运算指令,和ALU有关,本质上不就是加法器那些产生的符号位吗?)才会修改PSW寄存器里面的标志位,cmp指令本质上就是做了一个减法(但是结果不保存,只改变符号位),产生了符号位,然后条件转移指令再根据减法所产生的标志位(去PSW寄存器中获取)来决定要不要进行跳转!!!

六、C语言循环语句的汇编实现
i++后面紧跟的就是cmp,一旦越界就跳出循环
for:①先初始化,第一次直接判断是否跳出循环
②循环主体&i++③cmp i ,cnt(没结束就往上跳是for循环的一大重要特征!)

七、C语言函数调用的汇编视角


x86的push和pop默认是按照4字节压栈/出栈的
esp指向的是栈顶的位置(有元素)
push eax:①先sub esp,4 ②再mov [esp],eax
pop eax:①先mov eax,[esp] ②再add esp,4
call eax:①push eip ②jmp eax
ret:pop eip(默认是ret 4)


真实的堆栈以及函数调用:

所谓堆栈平衡就是函数调用前和调用后esp和ebp的位置保持不变!


试试看能不能画到堆栈平衡?
外平栈(默认采用的调用约定):cdcall(右左,外平栈:add esp,8)
内平栈:stdcall(右左,内平栈:ret 8(相当于add esp,8))

注意:一个线程里面的所有函数都使用同一个堆栈
int main(){
fun(2,3); push 3 push 2 call fun(push eip + jmp fun)
}
fun:

八、CICS和RISC指令集的对比


你RISC只能通过寄存器来访存,寄存器可不得比CICS多吗?

相关文章:
2024王道考研计算机组成原理——指令系统
零、本章概要 指令寻址:解决的是PC"1"的问题 数据寻址:使用寄存器/内存/结合 基址寻址:用于多道程序的并发执行 直接寻址:call 0x12345678 变址寻址:esi edi用于循环,因为使用直接寻址需要一堆…...
vscode中如何将cmd设置为默认终端
vscode中如何将cmd设置为默认终端?下面本篇文章给大家介绍一下vscode中设置默认终端为cmdPowerShelWSL等的方法,希望对需要的朋友有所协助! 一、快捷键(CtrlShiftP打开命令面板,输入select选择“SelectDefaultProfil …...
Unity UGUI 循环滑动列表实现思路及简单代码实现
前言: 自己之前其实比着书上实现过一个循环滑动列表,并且商业化到了项目里,上线后也在用。可后来怎么也想不起来细节,看着之前的代码也看不很懂。这次复习一下,希望真能理解它的本质,也记录一下࿰…...
贪心算法(1)--经典贪心算法
目录 一、活动安排问题 二、最优装载问题 三、分数背包问题 四、多机调度问题 一、活动安排问题 1、策略 活动安排问题:设有n个活动的集合E{1,2,...,n},每个活动i都有一个使用该资源的起始时间和一个结束时间,且。如果选择了活动i则它在…...
Nginx负载均衡和备份和故障转移
如果你想要两台 Nginx 服务器配置访问同一个链接,通常意味着你可能想要以下几种配置: 负载均衡:两台 Nginx 服务器都工作,当访问者请求资源时,流量会在这两台服务器之间进行均衡分配。备份和故障转移:其中…...
Android-Framework 三方应用默认权限都不弹窗
代码位置:frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java -1853,10 1853,10 public class PackageManagerService extends IPackageManager.StubmPermissionCallback);}- final String packageName res.pkg.application…...
TX Text Control.NET For WPF 32.0 Crack
TX Text Control 支持VISUAL STUDIO 2022、.NET 5 和 .NET 6 支持 .NET WPF 应用程序的文档处理 将文档编辑、创建和 PDF 生成添加到您的 WPF 应用程序中。 视窗用户界面 功能齐全的文档编辑器 TX Text Control 是一款完全可编程的丰富编辑控件,它在专为 Visual Stu…...
使用Go语言测试Redis性能
1. 前言 Redis是一个高性能的键值存储数据库,常用于缓存、队列、排行榜等场景。在实际应用中,我们需要对Redis的性能进行测试,以便了解其在不同场景下的表现。本文将介绍如何使用Go语言测试Redis的性能。 2. 环境准备 在开始测试前&#x…...
【Javascript】运算符(赋值,算术,自增,自减)
目录 赋值 算术 单个变量: 多个变量: 在字符串,数组中充当连接符 自符串与字符串 数组与数组 数组与字符串 自增与自减 前置 自增 自减 后置 自增 自减 赋值 var a 1;算术 单个变量: var a 1;a 1;console.l…...
Redis数据类型——list类型数据的扩展操作
1.list阻塞式数据获取 2.list类型数据业务场景...
[论文笔记]NEZHA
引言 今天带来华为诺亚方舟实验室提出的论文NEZHA,题目是 针对中文中文语言理解神经网络上下文表示(NEural contextualiZed representation for CHinese lAnguage understanding),为了拼出哪吒。 预训练语言模型由于具有通过对大型语料库进行预训练来捕获文本中深层上下文信…...
【Linux】认识协议
目录 一、应用层二、协议三、序列化和反序列化 一、应用层 之前的socket编程,都是在通过系统调用层面,如今我们来向上打通计算机网络。认识应用层的协议和序列化与反序列化 我们程序员写的一个个解决我们实际问题, 满足我们日常需求的网络程序, 都是在应…...
Hadoop3教程(三十四):(生产调优篇)MapReduce生产经验汇总
文章目录 (164)MR跑得慢的原因(165)MR常用调优参数Map阶段Reduce阶段 (166)MR数据倾斜问题参考文献 (164)MR跑得慢的原因 MR程序执行效率的瓶颈,或者说当你觉得你的MR程…...
Unity⭐️Win和Mac安卓打包环境配置
文章目录 🟥 配置Android SDK1️⃣ 配置 SDK Platforms2️⃣ 配置 SDK Tools🎁 Android SDK Build-Tools🎁 Android SDK Command-line Tools(latest)🎁 Android SDK Tools(Obsolete)🟧 配置NDK🟩 配置JDK前情提示: 此方法适用于Windows/Mac 在配置时注意开启 🪜 …...
STM32F4XX之串口
一、标准串口(UART)介绍 1、通信协议相关概念 1.1同步通信和异步通信 (1)同步通信:两个器件之间共用一个时钟线,要发送的数据在时钟的作用下一位一位发送出去。 (2)异步通信:指两个器件之间没…...
【J-Long Group Limited】申请1500万美元纳斯达克IPO上市
来源:猛兽财经 作者:猛兽财经 猛兽财经获悉,总部位于中国香港的J-Long Group Limited(简称:J-Long)近期已向美国证券交易委员会(SEC)提交招股书,申请在纳斯达克IPO上市&…...
上传文件到google drive
参考:使用 Python 将文件上传到 Google 云端硬盘_迹忆客 第 1 步:Google API Playground 我们可以通过搜索 Google 找到更多关于 Google API Playground 的信息。 我们必须单击第一个链接才能继续前进。 选择第一个链接后,我们会自动进入下一…...
用VLOOKUP快速合并两个表格
一、前言 上周五微信收到运营提过来的需求,第一句话:帮我提取一下1号门店的库存数据,马上登录系统下载一份库存数据给到他然后专心读代码,过一会微信第二句话:帮我提取一下1号门店商品半年/一年的销量数据,…...
Vue ref属性
Vue中的ref属性可以用来对HTML元素或者是对组件进行唯一标识。 一、设置ref属性 只需要在元素或者是组件后跟上如下语法即可: ref"标识名" 二、获取元素或对象 我们可以用如下方法获取我们设置ref的元素或组件: this.$refs.标识名 第一个输…...
【python入门】函数,类和对象
【大家好,我是爱干饭的猿,本文重点介绍python入门的函数,高阶函数,python中的类和对象,模块的作用等。 后续会继续分享其他重要知识点总结,如果喜欢这篇文章,点个赞👍,关…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...
Linux 内存管理实战精讲:核心原理与面试常考点全解析
Linux 内存管理实战精讲:核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用,还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...
腾讯云V3签名
想要接入腾讯云的Api,必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口,但总是卡在签名这一步,最后放弃选择SDK,这次终于自己代码实现。 可能腾讯云翻新了接口文档,现在阅读起来,清晰了很多&…...
es6+和css3新增的特性有哪些
一:ECMAScript 新特性(ES6) ES6 (2015) - 革命性更新 1,记住的方法,从一个方法里面用到了哪些技术 1,let /const块级作用域声明2,**默认参数**:函数参数可以设置默认值。3&#x…...
智能体革命:企业如何构建自主决策的AI代理?
OpenAI智能代理构建实用指南详解 随着大型语言模型(LLM)在推理、多模态理解和工具调用能力上的进步,智能代理(Agents)成为自动化领域的新突破。与传统软件仅帮助用户自动化流程不同,智能代理能够自主执行工…...
linux设备重启后时间与网络时间不同步怎么解决?
linux设备重启后时间与网络时间不同步怎么解决? 设备只要一重启,时间又错了/偏了,明明刚刚对时还是对的! 这在物联网、嵌入式开发环境特别常见,尤其是开发板、树莓派、rk3588 这类设备。 解决方法: 加硬件…...
