深入理解计算机系统学习笔记

1.算术和逻辑操作

下图是一些整数和逻辑操作

这些操作被分为四组:加载有效地址、一元操作、二元操作和移位。二元操作有两个操作数,而一元操作有一个操作数。

1.1加载有效地址

加载有效地址(load effective address)指令 leaq 实际上是 movq 指令的变形。它的指令形式是从内存读数据到寄存器,但实际上它根本就没有引用内存。它的第一个操作数看 上去是一个内存引用,但该指令并不是从指定的位置读人数据,而是将有效地址写人到目的操作数。

为了说明leaq在编译出的代码中的使用,使用下面示例说明

long scale(long x, long y, long z){

long t = x + 4 * y + 12 *z;

return t; }

编译时,该函数的算术运算以三条leaq指令实现,

long scale(long x, long y, long z)

x in %rdi, y in %rsi, z in %rdx

scale:

leaq (%rdi,%rsi,4), %rax 

leaq  (%rdx,%rdx,2), %rdx

leaq (%rd%rax,x,4), %rax

ret

这三条指令代表的含义是:

x+4y

z+ 2z

x+4y +12z

leaq指令能执行加法和有限形式的乘法,在编译如上简单的算术表达式时,是很有用处的。

1.2 —元和二元操作

第二组中的操作是一元操作,只有一个操作数,既是源又是目的。

这个操作数可以是一个寄存器,也可以是一个内存位置。如果操作数是寄存器,那么指令会直接操作这个寄存器中的值。如果操作数是内存位置,那么指令会从内存中加载数据到寄存器中,然后执行操作,并将结果写回到同一个内存位置中。

比如说,指令incq(%rsp)会使栈顶的8字节元素加1。这种语法让人想起C语言中的加1运算符(++)和减1运算符(--)。

第三组是二元操作,其中,第二个操作数既是源又是目的。这种语法让人想起C语言中的赋值运算符,例如x-=y。

源操作数是第一个,目的操作数是第二个。例如,指令subq %rax,%rdx 使寄存器%rdx的值减去%rax中的值。

第一个操作数可以是立即数、寄存器或是内存位置。

第二个操作数可以是寄存器或是内存位置。

注意, 当第二个操作数为内存地址时,处理器必须从内存读出值,执行操作,再把结果写回内存。

1.3 移位操作

最后一组是移位操作,先给出移位量,然后第二项给出的是要移位的数。可以进行算术和逻辑右移。

移位量可以是一个立即数,或者放在单字节寄存器%c1中。

示例:salq $4, %rax

将 %rax 中的值左移 4 位

1.4特殊的算术操作

下图描述的是支持产生两个64位数字的全128位乘积以及整数除法的指令。

2.1控制

到目前为止,我们只考虑了直线代码的行为,也就是指令一条接着一条顺序地执行。

c语言中的某些结构,比如条件语句、循环语句和分支语句,要求有条件的执行,根据数据测k的结果来决定操作执行的顺序。机器代码提供两种基本的低级机制来实现有条件的行为:测试数据值,然后根据测试的结果来改变控制流或者数据流。

通过使用jump指令可以改变一组机器代码指令的执行顺序,jump指令指定控制应该被传递到程序的某个其他部分,可能是依赖于某个测试的结果。编译器必须产生构建在这种低级机制基础之上的指令序列,来实现C语言的控制结构。

3.6.1 条件码

除了整数寄存器,CPU还维护着一组单个位的条件码(condition code)寄存器,它们描述了最近的算术或逻辑操作的属性。可以检测这些寄存器来执行条件分支指令。

最常用 的条件码有:

CF:进位标志。最近的操作使最高位产生了进位。可用来检查无符号操作的溢出。

ZF:零标志。最近的操作得出的结果为0。

SF:符号标志。最近的操作得到的结果为负数。

OF:溢出标志。最近的操作导致一个补码溢出一正溢出或负溢出。

leaq 指令不改变任何条件码,因为它是用来进行地址计算的。。对于逻辑操作,例如XOR,进位标志和溢出标志会设 置成0。对于移位操作,进位标志将设置为最后一个被移出的位,而溢出标志设置为0。

2.2 访问条件码

条件码通常不会直接读取,常用的使用方法有三种:

1)可以根据条件码的某种组合, 将一个字节设置为0或者1,2)可以条件跳转到程序的某个其他的部分,3)可以有条件地 传送数据。

set指令

一条SET指令的目的操作数是低位单字节寄存器元素(图3-2)之一,或是一个字节的内存位置,指令会将这个字节设置成0或者1。

2..3 跳转指令

正常执行的情况下,指令按照它们出现的顺序一条一条地执行。跳转(jump)指令会导 致执行切换到程序中一个全新的位置。

示例:

jmp .LI

movq (%rax) ,%rdx

.LI:

指令jmp .LI会导致程序跳过movq指令,而从.LI:指令后面开始执行。

jmp指令是无条件跳转。它可以是直接跳转,即跳转目标是作为指令的一部分编码的;也可以是间接跳转,即跳转目标是从寄存器或内存位置中读出的。

2.4 跳转指令的编码

跳转指令有几种不同的编码,但是最常用都是PC相对的(PC-relative)。也就是,它们会将目标指令 的地址与紧跟在跳转指令后面那条指令的地址之间的差作为编码。这些地址偏移量可以编 码为1、2或4个字节。

第二种编码方法是给出 “绝对” 地址,用4个字节直接指定目标。 汇编器和链接器会选择适当的跳转目的编码

2.5 用条件控制来实现条件分支

将条件表达式和语句从C语言翻译成机器代码,最常用的方式是结合有条件和无条件跳转。

汇编代码层面的条件控制类似于 c 语言的 goto 语句。汇编语言使用条件码和条件跳转来起到和 c 语言中 if 相似的作用。

2.6 用条件传送来实现条件分支

实现条件操作的传统方法是通过使用控制的条件转移。这种机制简单而通用,但是在现代 处理器上,它可能会非常低效。一种替代的策略是使用数据的条件转移。这种方法计算一个条件操作的两种结果,然后再根据条件是否满足从中选取一个。只有在一些受限制的情况中,这种策略才可行,但是如果可行,就可以用一条简单的条件传送指令来实现它,条件传送指令更符合现代处理器的性能特性。

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

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

相关文章

Pulsar3.2 Function的介绍与使用

概念 Function 步骤 Pulsar Functions是运行在Pulsar上面的计算框架,输入和输出都是基于Pulsar的Topic。通过使用Function可以对进入Pulsar集群的消息进行简单的清洗、计算,这样不仅避免额外部署单独的流处理引擎(SPE),最大限度的提高开发/…

【力扣hot100】刷题笔记Day14

前言 又是新的一周,快乐的周一,快乐地刷题,今天把链表搞完再干活! 114. 二叉树展开为链表 - 力扣(LeetCode) 前序遍历 class Solution:def flatten(self, root: Optional[TreeNode]) -> None:if not r…

Bicycles(变形dijkstra,动态规划思想)

Codeforces Round 918 (Div. 4) G. Bicycles G. Bicycles 题意: 斯拉夫的所有朋友都打算骑自行车从他们住的地方去参加一个聚会。除了斯拉维奇,他们都有一辆自行车。他们可以经过 n n n 个城市。他们都住在城市 1 1 1 ,想去参加位于城市…

【Java程序员面试专栏 算法思维】四 高频面试算法题:回溯算法

一轮的算法训练完成后,对相关的题目有了一个初步理解了,接下来进行专题训练,以下这些题目就是汇总的高频题目,本篇主要聊聊回溯算法,主要就是排列组合问题,所以放到一篇Blog中集中练习 题目关键字解题思路时间空间全排列回溯算法【元素无重不可复选】构造全排列树,用使…

kafka三节点集群平滑升级过程指导

一、前言 Apache Kafka作为常用的开源分布式流媒体平台,可以实时发布、订阅、存储和处理数据流,多用于作为消息队列获取实时数据,构建对数据流的变化进行实时反应的应用程序,已被数千家公司用于高性能数据管道、流分析、数据集成和任务关键型…

Redis String 类型底层揭秘

目录 前言 String 类型低层数据结构 节省内存的数据结构 前言 Redis 的 string 是个 “万金油” ,这么评价它不为过. 它可以保存Long 类型整数,字符串, 甚至二进制也可以保存。对于key,value 这样的单值,查询以及插…

详解Kotlin中run、with、let、also与apply的使用和区别

Kotlin作为一种现代、静态类型的编程语言,不仅提供了丰富的特性,还提供了极具表现力的函数:run, with, let, also, 和 apply。理解这些函数的不同之处对于编写高效、易于维护的代码至关重要。 函数对比表 函数对象引用返回值使用场景runthi…

猜数游戏(个人学习笔记黑马学习)

案例需求 定义一个数字(1~10,随机产生),通过3次判断来猜出来数字 案例要求: 1.数字随机产生,范围1-10 2.有3次机会猜测数字,通过 3.层嵌套判断实现每次猜不中,会提示大了或小了 提示,通过如下代…

【海贼王的数据航海:利用数据结构成为数据海洋的霸主】链表—单链表

目录 1 -> 链表 1.1 -> 链表的概念及结构 1.2 -> 链表的分类 2 -> 无头单向非循环链表(单链表) 2.1 -> 接口声明 2.2 -> 接口实现 2.2.1 -> 动态申请一个结点 2.2.2 -> 单链表的打印 2.2.3 -> 单链表的尾插 2.2.4 -> 单链表的头插 2.…

消息中间件篇之RabbitMQ-消息不丢失

一、生产者确认机制 RabbitMQ提供了publisher confirm机制来避免消息发送到MQ过程中丢失。消息发送到MQ以后,会返回一个结果给发送者,表示消息是否处理成功。 当消息没有到交换机就失败了,就会返回publish-confirm。当消息没有到达MQ时&…

2.27数据结构

1.链队 //link_que.c #include "link_que.h"//创建链队 Q_p create_que() {Q_p q (Q_p)malloc(sizeof(Q));if(qNULL){printf("空间申请失败\n");return NULL;}node_p L(node_p)malloc(sizeof(node));if(LNULL){printf("申请空间失败\n");return…

DETR(1):论文详解

文章目录 1. DETR 模型结构2.损失函数2.1 预测结果和GT 的匹配2.2 训练的loss计算3.实验3.1 大物体表现效果好3.2 Transformer Encoder 和Decoder的作用3.3 object query4. 伪代码5. 结论

【《高性能 MySQL》摘录】第 2 章 MySQL 基准测试

文章目录 2.1 为什么需要基准测试2.2 基准测试的策略2.2.1 测试何种指标 2.3 基准测试方法2.3.1 设计和规划基准测试2.3.2 基准测试应该运行多长时间2.3.3 获取系统性能和状态2.3.4 获得准确的测试结果2.3.5 运行基准测试并分析结果2.3.6 绘图的重要性 2.4 基准测试工具…

IntelliJ IDEA 2023:创新不止步,开发更自由 mac/win版

IntelliJ IDEA 2023激活版是一款强大而智能的集成开发环境(IDE),为开发者提供了一系列先进的功能和工具,帮助他们更高效地编写、调试和测试代码。 IntelliJ IDEA 2023 软件获取 IntelliJ IDEA 2023继承了其前代版本的优秀基因,并在此基础上进…

2月28日代码随想录二叉搜索树中的众数

摸了一个寒假了,得赶一赶了 251.二叉搜索树中的众数 给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。 如果树中有不止一个众数&am…

虚拟机JVM

虚拟机 1、定义jvm 假想计算机 运行在操作系统之上 和硬件之间没有直接交互 包括 一套字节码指令、寄存器、栈、垃圾回收、堆 一个存储方法域 jvm:承担一个翻译工作,动态的将java代码编译成操作系统可以识别的机器码。 从软件层面屏蔽了不同操作系统在底层硬件与指…

查看cuda和cudnn版本

查看cuda 打开命令提示符(Windows键 R,然后输入cmd并回车)。输入nvcc --version或者nvcc -V来获取Cuda的版本信息。 查看cudnn版本 查看Cudnn版本: 进入Cuda安装目录,通常位于C:\Program Files\NVIDIA GPU Computi…

Doris——荔枝微课统一实时数仓建设实践

目录 一、业务介绍 二、早期架构及痛点 2.1 早期架构 2.2 架构痛点 三、技术选型 四、新的架构及方案 五、搭建经验 5.1 数据建模 5.2 数据开发 5.3 库表设计 5.4 数据管理 5.4.1 监控告警 5.4.2 数据备份与恢复 六、收益总结 七、未来规划 原文大佬这篇Doris腾…

STM32 Cubemx配置SPI编程(使用Flash模块)

文章目录 前言一、W25Q64模块介绍二、STM32Cubemx配置SPI三、SPI HAL库操作函数分析3.1查询方式3.2中断方式 四、Flash时序分析1.读器件ID指令2.写使能3.擦除扇区4.页编程5.读数据6.读状态寄存器 五、Flash驱动程序编写1.代码编写测试 总结 前言 本篇文章来为大家讲解一下Flas…

安装极狐GitLab Runner并测试使用

本文继【新版极狐安装配置详细版】之后继续 1. 添加官方极狐GitLab 仓库: 对于 RHEL/CentOS/Fedora: curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh" | sudo bash2. 安装最新版本的极狐G…