从头开发一个RISC-V的操作系统(五)汇编语言编程

文章目录

  • 前提
  • RISC-V汇编语言入门
  • RISC-V汇编指令总览
    • 汇编指令操作对象
    • 汇编指令编码格式
    • add指令介绍
    • 无符号数
  • 练习
  • 参考链接

目标:通过这一个系列课程的学习,开发出一个简易的在RISC-V指令集架构上运行的操作系统。

前提

这个系列的大部分文章和知识来自于:[完结] 循序渐进,学习开发一个RISC-V上的操作系统 - 汪辰 - 2021春,以及相关的github地址。

在这个过程中,这个系列相当于是我的学习笔记,做个记录。

RISC-V汇编语言入门

能手写汇编代码的,在我的心目中,都是巨佬。只有明白底层硬件的人,才有可能去写汇编。

一个完整的RISC-V汇编程序有多条语句(statement)组成。一个典型的RISC-V汇编语句由3部分组成:
[label:] [operation] [comment]

  • label:任何以冒号结尾的标识符都被认为是一个标号。
  • operation可以有多种类型
    • instruction:直接对应二进制机器指令的字符串
    • pseudo-instruction:为了提高编写代码的效率,可以用一条伪指令指示汇编器产生多条实际的指令
    • directive:通过类似指令的形式(以.开头),通知汇编器如何控制代码的产生,不对应具体的指令
    • macro:采用.macro/.endm自定义的宏
  • comment:注释,以#开始到当前行结束

RISC-V汇编指令总览

汇编指令操作对象

寄存器:在这个系列中,我们只有32个通用寄存器,x0~x31,这个在之前我们已经展示过了。在RISC-V中,Hart在执行算数逻辑运算时所操作的数据必须直接来自寄存器。

内存:Hart可以执行在寄存器和内存之间的数据读写操作;读写操作使用字节位基本单位进行寻址;RV32最多可以访问 2 32 2^{32} 232个字节的内存空间。

汇编指令编码格式

在这里插入图片描述
RV32由6种指令编码格式。每一条指令有32bits,funct7/funct3和opcode一起决定最终的指令类型。指令在内存中按照小端序排列。rs2,rs1,rd都是指的是寄存器(register),imm指的是立即数。
大端序:高字节存放在内存的低地址;小端序:低字节存放在内存的低地址。
下面这张表指出了opcode是如何与指令对应的。
在这里插入图片描述
opcode总共7bits,第0和第1位都是11,第2到第四位和第5到第6位不同,则代表着指令类型不同,使用addsub指令举例。
在这里插入图片描述
先看opcode0110011在表中对应着OP,add和sub都应该属于OP,然后funct3也相同,但是funct7不同,代表着它们一个是add,一个是sub。

这里介绍的只是一个概貌,更多信息还要自己学习。

add指令介绍

在这里插入图片描述
通过上面的图片就可以明白一条汇编指令是如何到二进制代码的。同时这一块视频中也有详细地讲解。

无符号数

我们知道有符号数在计算机中都是使用二进制补码的形式保存的,最高位为符号位,0代表正数,1代表负数。正数的补码不变,负数的补码=反码+1。

练习

这里我们带大家做一个add2的练习。
汇编源码为:

# Add
# Format:
#	ADD RD, RS1, RS2
# Description:
#	The contents of RS1 is added to the contents of RS2 and the result is 
#	placed in RD..text			# Define beginning of text section.global	_start		# Define entry _start_start:li x6, 1		# x6 = 1li x7, -2		# x7 = -2add x5, x6, x7		# x5 = x6 + x7stop:j stop			# Infinite loop to stop execution.end			# End of file

make 以后,我们使用make code查看这个程序的二进制代码,然后逐行进行分析,如下:


test.elf:     file format elf32-littleriscvDisassembly of section .text:80000000 <_start>:.text			# Define beginning of text section.global	_start		# Define entry _start_start:li x6, 1		# x6 = 1
80000000:	00100313          	li	t1,1li x7, -2		# x7 = -2
80000004:	ffe00393          	li	t2,-2add x5, x6, x7		# x5 = x6 + x7
80000008:	007302b3          	add	t0,t1,t28000000c <stop>:stop:j stop			# Infinite loop to stop execution
8000000c:	0000006f          	j	8000000c <stop>

其他都没什么好说的,主要就是这个li指令以及add这个指令。add x5,x6,x7这个我们在上面展示过了,这里主要解释下li这个伪指令。
在这里插入图片描述
这里我们先从其他博客那里拿过来一个结论,
在这里插入图片描述

li伪指令把一个立即数imm加载到rd寄存器中。当imm在 [ − 2 11 , 2 11 − 1 ] [-2^{11} , 2^{11-1}] [211,2111]范围内(也就是[-2048~2047))的时候,li被转化成下面这条实际指令:

addi rd, x0,imm #rd=imm+0
x0是一个特殊的寄存器,值为0且永远不会改变

所以add x7, x0, -2 对应的二进制为:111111111110 00000 000 00111 0010011,前面的111111111110代表了-2,它是以二进制补码存储的;00000代表了寄存器x0,000是funct,00111代表了寄存器x7,最后的0010011则是opcode。和我们输出的hex一样。

那么当立即数imm不在这个范围,但在32位有符号数的范围内(也就是[-2147482648~-2048)以及(+2047~+2147482647])的时候,一条addi指令显然是不够了。 这时候就需要lui指令。

假设我们有这样的一条语句add x7, -3000,那么它对应的二进制是多少呢?先看它的二进制,如下图:
在这里插入图片描述
在立即数为-3000的情况下,一条li伪指令被分为了两条汇编指令luiaddiaddi我们已经在上面介绍过了,下面给出lui指令的说明。
在这里插入图片描述
看这个似乎有点懵,我们直接说怎么将-3000写入到x7寄存器的。
-3000的32位二进制反码为1111 1111 1111 1111 1111 0100 0100 1000,先取第12到第31位(通过右移12位就可以得到第12到第31位),也就是1111 1111 1111 1111 1111共20位,构成lui这条指令1111 1111 1111 1111 1111 00111 0110111 = fffff3b7。对应的操作就是:将20位左移12位,并将低12位置0,写入到x7中。
再取-3000的第0到第11位0100 0100 1000加到x7寄存器中(x7 = x7 + imm[0:11]),对应的二进制指令就是0100 0100 1000 00111 000 00111 0010011 = 44838393,可以看到,和程序的结果一样。这样大家阶对li伪指令有了进一步的了解。

参考链接

  1. https://zhuanlan.zhihu.com/p/367085156

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

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

相关文章

uniapp - 微信小程序 - 使用uCharts的一些问题

文章目录 uniapp - 微信小程序 - 使用uCharts的一些问题一、开发者工具显示正常&#xff0c;真机调试统计图不随页面滚动二、数据过多开启滚动条&#xff0c;无法滑动滚动条三、饼图点击不显示提示窗/点击位置bug、多个同类型统计图点击不显示提示框问题四、 formatter 自定义 …

抖音-引流私域转化模式1.0现场视频,从抖音源源不断把人加到私域,

抖音-引流私域转化模式1.0现场视频&#xff0c;从抖音源源不断把人加到私域&#xff0c;让加到私域的粉丝买单 抖音-引流私域转化模式1.0现场视频&#xff0c;从抖音源源不断把人加到私域 - 百创网-源码交易平台_网站源码_商城源码_小程序源码 课程内容&#xff1a; 01.第一…

SpringBoot3整合RabbitMQ之三_工作队列模型案例

SpringBoot3整合RabbitMQ之三_工作队列模型案例 文章目录 SpringBoot3整合RabbitMQ之三_工作队列模型案例2. 工作队列模型1. 消息发布者1. 创建工作队列的配置类2. 发布消费Controller 2. 消息消费者One3. 消息消费者Two4. 消息消费者Three5. 输出结果 2. 工作队列模型 1. 消息…

mysql_secure_installation初始化数据库报Access denied

使用mysql_secure_installation配置时出错&#xff1a; 可能输入密码错误&#xff0c;重新复制&#xff0c;粘贴密码。 或者&#xff1a; 登录mysql&#xff0c;设置密码&#xff0c;然后再设置权限。 mysql -u root -p [输入密码] sql>set passwordpassword("newPa…

数字人解决方案——Champ单个视频单张图像生成可控且一致的人体视频生成

概述 Champ是阿里巴巴集团、南京大学和复旦大学的研究团队共同提出了一种创新的人体动画生成技术&#xff0c;Champ能够在仅有一段原始视频和一张静态图片的情况下&#xff0c;激活图片中的人物&#xff0c;使其按照视频中的动作进行动态表现&#xff0c;极大地促进了虚拟主播…

鸿蒙ArkTS开始实例:【canvas实现签名板功能】

使用ArkTS中的canvas实现签名板的功能&#xff0c;canvas画布大家都很熟悉&#xff0c;我们会用它经常实现一些画板或者图表、表格之类的功能。canvas签名板是我在开发APP过程中实现的一个功能&#xff0c;开发过程中也是遇到比较多的问题。我会按照以下几点来讲解开发整个过程…

如何从应用商店Microsoft Store免费下载安装HEVC视频扩展插件

在电脑上打开一张HEIC类型的图片提示缺少HEVC解码器&#xff0c;无法打开查看&#xff0c;现象如下&#xff1a; 这种情况一般会提示我们需要下载安装HEVC解码器&#xff0c;点击“立即下载并安装”会跳转到应用商店&#xff0c;但是我们发现需要付费7元才能下载安装 免费安装…

【Linux系列】“dev-node1“ 运行的操作系统分析

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

C++从入门到精通——this指针

this指针 前言一、this指针的引出问题 二、this指针的特性三、例题什么时候会出现编译报错什么时候会出现运行崩溃this指针存在哪里this指针可以为空吗 四、C语言和C实现Stack的对比C语言实现C实现 前言 this指针是一个特殊的指针&#xff0c;在C类的成员函数中使用。它指向调…

阿里面试总结

ThreadLocal 线程变量存放在当前线程变量中&#xff0c;线程上下文中&#xff0c;set将变量添加到threadLocals变量中 Thread类中定义了两个ThreadLocalMap类型变量threadLocals、inheritableThreadLocals用来存储当前操作的ThreadLocal的引用及变量对象&#xff0c;把当前线程…

Redis 之集群模式

一 集群原理 集群&#xff0c;即Redis Cluster&#xff0c;是Redis 3.0开始引入的分布式存储方案。 集群由多个节点(Node)组成&#xff0c;Redis的数据分布在这些节点中。 集群中的节点分为主节点和从节点&#xff1a;只有主节点负责读写请求和集群信息的维护&#xff1b;从…

【cocos creator】【编辑器插件】cocos creator文件复制时,解决cocos creator uuid冲突

&#xff01;&#xff01;&#xff01;修改前先备份 1、将文件夹放在packages文件夹下 2、打开项目&#xff0c;选择要刷新uuid的文件夹 3、菜单栏点击 扩展->refresh-uuid 4、等控制台提示&#xff1a;资源uuid刷新完成&#xff0c;重启项目&#xff08;&#xff01;&#…

JavaEE 初阶篇-深入了解线程池(线程池创建、线程池如何处理任务)

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 线程池概述 1.1 线程池的优点 1.2 不使用线程池的问题 1.3 线程池的工作原理图 1.4 如何创建线程池&#xff1f; 2.0 通过 ThreadPoolExecutor 类自定义创建线程…

基于 Vue3 + Webpack5 + Element Plus Table 二次构建表格组件

基于 Vue3 Webpack5 Element Plus Table 二次构建表格组件 文章目录 基于 Vue3 Webpack5 Element Plus Table 二次构建表格组件一、组件特点二、安装三、快速启动四、单元格渲染配置说明五、源码下载地址 基于 Vue3 Webpack5 Element Plus Table 二次构建表格组件&#x…

有限的边界-DDD领域

从广义上讲&#xff0c;领域&#xff08;Domain&#xff09;即是一个组织所做的事情以及其中所包含的一切。商业机构通常会确定一个市场&#xff0c;然后在这个市场中销售产品和服务。每个组织都有它自己的业务范围和做事方式。这个业务范围以及在其中所进行的活动便是领域。当…

开源数据湖iceberg, hudi ,delta lake, paimon对比分析

Iceberg, Hudi, Delta Lake和Paimon都是用于大数据湖(Data Lake)或数据仓库(Data Warehouse)中数据管理和处理的工具或框架,但它们在设计、功能和适用场景上有所不同。 Iceberg: Iceberg是用于大型分析表的高性能格式。Iceberg将SQL表的可靠性和简易性带入到大数据领域,同…

【运输层】传输控制协议 TCP

目录 1、传输控制协议 TCP 概述 &#xff08;1&#xff09;TCP 的特点 &#xff08;2&#xff09;TCP 连接中的套接字概念 2、可靠传输的工作原理 &#xff08;1&#xff09;停止等待协议 &#xff08;2&#xff09;连续ARQ协议 3、TCP 报文段的首部格式 &#xff08;1…

Embedding:跨越离散与连续边界——离散数据的连续向量表示及其在深度学习与自然语言处理中的关键角色

Embedding嵌入技术是一种在深度学习、自然语言处理&#xff08;NLP&#xff09;、计算机视觉等领域广泛应用的技术&#xff0c;它主要用于将高维、复杂且离散的原始数据&#xff08;如文本中的词汇、图像中的像素等&#xff09;映射到一个低维、连续且稠密的向量空间中。这些低…

能否安全地删除 Mac 资源库中的文件?

在管理Mac电脑存储空间时&#xff0c;用户确实可能考虑对资源库&#xff08;Library&#xff09;文件夹进行清理以释放空间。Mac资源库是一个系统及应用程序存放重要支持文件的地方&#xff0c;其中包括但不限于配置文件、临时文件、缓存、插件、偏好设置、应用程序支持数据等。…

注意!今明两天广东等地仍有较强降雨

中央气象台监测显示 进入4月以来 我国江南、华南北部强降雨 接连而至 湖南、江西、浙江中南部 福建大部、广东中北部等地降雨量 较常年同期偏多1倍以上 上述地区部分国家观测站 日雨量突破4月历史极值 截至4月7日早晨 广东广州、惠州、清远 韶关、河源等地部分地区 …