从头开发一个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.mzph.cn/news/799275.shtml

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

相关文章

VMware Intel i5-10400 安装Mac 14 Sonoma

目录 安装完后的效果安装前的准备创建虚拟机创建虚拟机&#xff0c;选择典型安装。选择ISO文件选择系统类型命名虚拟机设置磁盘完成 配置虚拟机文件修改配置文件 第一次运行虚拟机选择语言选择磁盘工具格式磁盘安装macOS Sonoma 其他问题登录Apple帐户 &#xff1a; MOBILEME_C…

单点登录系统设计

一、介绍 token鉴权最佳的实践场景就是在单点登录系统上。 在企业发展初期&#xff0c;使用的后台管理系统还比较少&#xff0c;一个或者两个。 以电商系统为例&#xff0c;在起步阶段&#xff0c;可能只有一个商城下单系统和一个后端管理产品和库存的系统。 随着业务量越来…

药店药品进销存管理系统软件可以对有效期管理查询以及对批号库存管理

药店药品进销存管理系统软件可以对有效期管理查询以及对批号库存管理 一、前言 以下软件操作教程以&#xff0c;佳易王药店药品进销存管理软件为例说明 软件文件下载可以点击最下方官网卡片——软件下载——试用版软件下载 软件可以对药品有效期进行管理查询&#xff0c;可以…

【C++进阶】哈希表(哈希函数、哈希冲突、开散列、闭散列)

&#x1fa90;&#x1fa90;&#x1fa90;欢迎来到程序员餐厅&#x1f4ab;&#x1f4ab;&#x1f4ab; 主厨&#xff1a;邪王真眼 主厨的主页&#xff1a;Chef‘s blog 所属专栏&#xff1a;c大冒险 总有光环在陨落&#xff0c;总有新星在闪烁 引言&#xff1a; 我们之前…

【Frida】【Android】 10_爬虫之WebSocket协议分析

&#x1f6eb; 系列文章导航 【Frida】【Android】01_手把手教你环境搭建 https://blog.csdn.net/kinghzking/article/details/136986950【Frida】【Android】02_JAVA层HOOK https://blog.csdn.net/kinghzking/article/details/137008446【Frida】【Android】03_RPC https://bl…

实现第一个动态链接库 游戏插件 成功在主程序中运行 dll 中定义的类

devc 5.11编译环境 dll编译环境设置参考 Dev c C语言实现第一个 dll 动态链接库 创建与调用-CSDN博客 插件 DLL代码和主程序代码如下 注意 dll 代码中的class 类名需要 和主程序 相同 其中使用了函数指针和强制类型转换 函数指针教程参考 以动态库链接库 .dll 探索结构体…

HBase详解(2)

HBase 结构 HRegion 概述 在HBase中&#xff0c;会从行键方向上对表来进行切分&#xff0c;切分出来的每一个结构称之为是一个HRegion 切分之后&#xff0c;每一个HRegion会交给某一个HRegionServer来进行管理。HRegionServer是HBase的从节点&#xff0c;每一个HRegionServ…

elementPlus el-table动态列扩展及二维表格

1、循环列数据源&#xff0c;动态生成列 <template><div><el-table ref"table" :data"pageData.tableData" stripe style"width: 100%"><el-table-column v-for"column in pageData.columns" :key"column.p…

尚硅谷html5+css3(1)html相关知识

1.基本标签&#xff1a; <h1>最大的标题字号 <h2>二号标题字号 <p>换行 2.根标签<html> 包括<head>和<body> <html><head><title>title</title><body>body</body></head> </html> 3…

162 Linux C++ 通讯架构实战16,UDP/TCP协议的优缺点,使用环境对比。UDP 服务器开发

UDP/TCP协议的优缺点 TCP :面向连接的&#xff0c;可靠数据包传输。对于不稳定的网络层&#xff0c;采取完全弥补的通信方式。丢包重传 优点&#xff1a;稳定&#xff0c;数据流量稳定&#xff0c;速度稳定&#xff0c;顺序稳定 缺点&#xff1a;传输速度慢&…

青藏铁路双寨物流基地扩能改造工程接触网第一杆成功组立

4月2日凌晨&#xff0c;随着吊钩缓缓落下&#xff0c;在中铁电气化局北京电化公司现场作业人员的紧张操作下&#xff0c;青藏铁路双寨物流基地扩能改造工程首根接触网支柱稳稳落在基础上&#xff0c;标志着双寨物流基地扩能改造进入全面施工阶段。 双寨物流基地扩能改造工程包含…

Part1.Transformer架构

构成&#xff1a; 【手把手教你用Pytorch代码实现Transformer模型&#xff01;从零解读(Pytorch版本&#xff09;-哔哩哔哩】 https://b23.tv/o283hzU

JavaScript逆向爬虫——使用Python模拟执行JavaScript

使用Python模拟执行JavaScript 通过一些调试&#xff0c;我们发现加密参数token是由encrypt方法产生的。如果里面的逻辑相对简单的话&#xff0c;那么我们可以用Python完全重写一遍。但是现实情况往往不是这样的&#xff0c;一般来说&#xff0c;一些加密相关的方法通常会引用…

摄像头校准漫反射板提高识别物体

摄像头校准漫反射板是一种用于摄像头校准的重要工具。在摄像头成像过程中&#xff0c;由于各种因素的影响&#xff0c;如光线、角度、镜头畸变等&#xff0c;会导致摄像头成像出现偏差。为了消除这些偏差&#xff0c;提高摄像头的成像质量&#xff0c;需要使用摄像头校准漫反射…

从头开发一个RISC-V的操作系统(四)嵌入式开发介绍

文章目录 前提嵌入式开发交叉编译GDB调试&#xff0c;QEMU&#xff0c;MAKEFILE练习 目标&#xff1a;通过这一个系列课程的学习&#xff0c;开发出一个简易的在RISC-V指令集架构上运行的操作系统。 前提 这个系列的大部分文章和知识来自于&#xff1a;[完结] 循序渐进&#x…

第十四讲:C语言字符函数和字符串函数

目录 1. 字符分类函数 2、字符转换函数 3. strlen的使⽤和模拟实现 4. strcpy 的使⽤和模拟实现 5. strcat 的使⽤和模拟实现 6. strcmp 的使⽤和模拟实现 7. strncpy 函数的使⽤ 8. strncat 函数的使⽤ 9. strncmp函数的使⽤ 10. strstr 的使⽤和模拟实现 11. strt…

mysql的索引类型与数据存储

mysql索引与类型 什么是索引&#xff1f; 索引&#xff08;Index&#xff09;是帮助MySQL高效获取数据的数据结构。我们可以简单理解为&#xff1a;快速查找排好序的一种数据结构。Mysql索引主要有两种结构&#xff1a;BTree索引和Hash索引。我们平常所说的索引&#xff0c;如…

校园圈子小程序,大学校园圈子,三段交付,源码交付,支持二开

介绍 在当今的数字化时代&#xff0c;校园社交媒体和在线论坛成为了学生交流思想、讨论问题以及分享信息的常用平台。特别是微信小程序&#xff0c;因其便捷性、用户基数庞大等特点&#xff0c;已逐渐成为构建校园社区不可或缺的一部分。以下是基于现有资料的校园小程序帖子发…

(已解决)引入本地bootstrap无效,bootstrap和jquery的引入

问题&#xff1a; 首先我是跟着张天宇老师下载的bootstrap文件&#xff0c;新建了一个css文件夹&#xff0c;但是这样子<link rel"stylesheet" type"text/css" src"./css/bootstrap.css">在index.html引入没有用。 解决办法: 1.把建立的…

【opencv】示例-dft.cpp 该程序演示了离散傅立叶变换 (dft) 的使用,获取图像的 dft 并显示其功率谱...

#include "opencv2/core.hpp" // 包含OpenCV核心功能头文件 #include "opencv2/core/utility.hpp" // 包含OpenCV实用程序头文件 #include "opencv2/imgproc.hpp" // 包含OpenCV图像处理头文件 #include "opencv2/imgcodecs.hpp" // 包…