自定义汇编语言(Custom Assembly Language) 和 Unix & Git

1. 什么是自定义汇编语言(Custom Assembly Language)?

汇编语言(Assembly Language)是一种低级编程语言 ,它直接与 CPU 指令集(Instruction Set Architecture, ISA)对应,每条指令都映射到机器码(Binary Code)。自定义汇编语言通常指:

  • 为特定 CPU 设计的汇编语言(如 x86、ARM、RISC-V)

  • 基于虚拟机(VM)的汇编语言(如 WebAssembly、JVM 的字节码)

  • 专用于特定系统的汇编指令集(如 GPU 汇编)

🛠️ 汇编语言的编程原则

  1. 寄存器操作 :使用 MOVADDSUB 等指令操作 CPU 寄存器。

  2. 内存管理 :手动处理 STACK(栈)和 HEAP(堆)。

  3. 条件跳转 & 循环 :使用 CMP + JMP(如 JEJNE)来实现分支逻辑。

  4. 系统调用(Syscall):调用操作系统提供的功能(如文件 I/O)。

示例(x86 汇编 - NASM 语法):

section .data
message db "Hello, Assembly!", 0 ; 定义字符串

section .text
global _start
_start:
mov edx, 16 ; 设置要输出的字符数量
mov ecx, message ; 指向 message 地址
mov ebx, 1 ; 文件描述符 (stdout)
mov eax, 4 ; syscall: sys_write
int 0x80 ; 触发中断,执行系统调用

mov eax, 1 ; syscall: sys_exit
xor ebx, ebx ; 退出状态码 0
int 0x80

  1. 2. Unix 简介

Unix 是一个强大且稳定的操作系统,强调多用户、多任务、权限管理 。许多现代操作系统(如 Linux、macOS、BSD)都基于 Unix 设计。

🔧 Unix 基础

  • 命令行操作 (Shell):lscdpwdgrep

  • 进程管理pskilltop

  • 文件权限chmodchown

  • 系统调用(Syscall) :用户程序调用内核功能(如 open()read()write()

示例

ls -l # 查看当前目录详细信息

chmod +x script.sh # 赋予脚本执行权限

ps aux # 显示所有进程

  1. 3. Git 简介

Git 是一种分布式版本控制系统(DVCS),主要用于代码管理、团队协作、历史追踪

Git 常用命令

复制代码
git init               # 初始化 Git 仓库
git clone <repo_url>   # 克隆远程仓库
git add file.txt       # 添加文件到暂存区
git commit -m "提交说明"  # 提交更改
git push origin main   # 推送到远程仓库
git pull origin main   # 拉取最新代码
git log                # 查看提交历史

2. 熟悉 Unix 基本命令

查看和切换目录

pwd # 显示当前目录(Print Working Directory)

ls # 列出当前目录下的文件和文件夹

ls -l # 详细信息(long format)

ls -a # 显示所有文件(包括隐藏文件)

ls -lh # 以可读格式显示文件大小(KB/MB)

cd /path # 进入指定目录

cd .. # 返回上一级目录

cd - # 返回上次访问的目录

创建、删除目录

mkdir myfolder # 创建目录

rmdir myfolder # 删除空目录

rm -r myfolder # 删除非空目录(慎用)

创建、复制、移动和删除文件

touch file.txt # 创建文件

cp file1.txt file2.txt # 复制文件

mv file.txt newname.txt # 重命名/移动文件

rm file.txt # 删除文件(不可恢复)

2.2 查看和编辑文件

cat file.txt # 显示文件内容

less file.txt # 分页查看文件(按 `q` 退出)

head -n 10 file.txt # 显示前 10 行

tail -n 10 file.txt # 显示后 10 行

nano file.txt # 使用 Nano 编辑器编辑文件

vim file.txt # 使用 Vim 编辑文件(高级)

2.3 用户管理

whoami # 显示当前用户

who # 查看当前在线用户

id # 显示当前用户的 UID 和 GID

passwd # 修改当前用户密码

sudo su # 切换到 root 用户(需要 sudo 权限)

2.4 权限管理

查看权限

ls -l file.txt

示例输出:

-rw-r--r-- 1 user user 1234 Mar 31 12:00 file.txt

  • -rw-r--r--:文件权限

  • user user:文件的所属用户和用户组

修改权限

chmod 644 file.txt # 允许所有人读取,只有文件所有者可以写
chmod +x script.sh # 赋予执行权限
chown newuser file.txt # 更改文件所有者

2.5 进程管理

ps aux # 显示所有进程

top # 动态显示进程信息(按 `q` 退出)

htop # 更美观的进程管理工具(需要安装)

kill PID # 终止进程(用 `ps aux` 找到 PID)

kill -9 PID # 强制终止进程

pkill name # 按进程名称终止

2.6 磁盘和存储管理

df -h # 显示磁盘空间使用情况

du -sh * # 查看当前目录下每个文件/文件夹的大小

mount # 查看挂载的磁盘

umount /dev/sdb1 # 卸载设备

2.7 搜索与查找

find /path -name "file.txt" # 按文件名查找

find / -size +100M # 查找大于 100MB 的文件

grep "error" file.txt # 在文件中查找 "error"

grep -r "keyword" /path/ # 递归搜索目录

2.8 网络管理

ping google.com # 检查网络连接

curl ifconfig.me # 查看公网 IP 地址

wget http://example.com/file.zip # 下载文件

netstat -tulnp # 查看当前网络连接

练习任务

你可以尝试以下任务来熟练 Unix 命令:

  1. 创建一个新目录 testdir 并进入它。

  2. 创建一个文本文件 notes.txt 并写入一些内容。

  3. 复制 notes.txtbackup.txt 并查看其内容。

  4. 查找 /etc 目录中所有 .conf 文件

  5. 杀死一个运行中的进程 (使用 ps aux 找到进程)。

  6. 查看你的磁盘使用情况 并找到大于 100MB 的文件。

3. 学习 Git 进行代码版本管理

Git 基础概念

🔹 Git 是什么?

Git 允许你追踪代码的每次修改,随时回溯历史,并与团队协作。

🔹 常见术语

术语 解释
Repository(仓库) 存储代码和历史记录的地方
Commit(提交) 记录代码的某次修改
Branch(分支) 独立的开发线,允许并行工作
Merge(合并) 将分支的更改合并到主分支
Remote(远程仓库) 存储在 GitHub、GitLab 等远程服务器的仓库

Git 安装与配置

安装 Git

Linux (Debian/Ubuntu)

sudo apt update

sudo apt install git

Mac (Homebrew)

brew install git

Windows 下载 Git 官方安装包 并安装。

配置 Git

安装完成后,设置用户名和邮箱:

git config --global user.name "你的名字"

git config --global user.email "你的邮箱"

检查配置:

git config --list

Git 基本操作

创建 Git 仓库

mkdir my_project # 创建新文件夹

cd my_project # 进入项目目录

git init # 初始化 Git 仓库

运行 git init 后,目录下会生成 .git 文件夹(隐藏文件),表示该目录已经是一个 Git 仓库。

添加文件并提交

touch file.txt # 创建新文件

echo "Hello Git" > file.txt # 写入内容

git status # 查看当前状态

git add file.txt # 添加到暂存区

git commit -m "第一次提交" # 提交更改

Git 运行机制

  1. git add 把文件添加到 暂存区(Staging Area)

  2. git commit 把暂存区的内容提交到 本地仓库(Local Repository)

查看提交历史

git log # 查看提交历史

git log --oneline # 简洁模式

git log --graph --all # 以图形方式查看

分支管理

创建和切换分支

git branch feature # 创建新分支
git checkout feature # 切换到新分支
git switch feature # (新方法)切换到新分支

合并分支

git checkout main

git merge feature # 将 feature 合并到 main

删除分支

git branch -d feature

远程仓库(GitHub / GitLab)

关联远程仓库

git remote add origin https://github.com/user/repo.git
git push -u origin main # 推送到远程仓库

拉取远程代码

git pull origin main # 获取最新代码

练习任务

1. 初始化一个 Git 仓库git init

2. 创建文件并提交git add + git commit

3. 创建一个分支并切换git branch + git checkout

4. 把代码推送到 GitHubgit push

4. 深入理解汇编语言的 CPU 指令集

1. 什么是 CPU 指令集?

CPU 指令集(Instruction Set Architecture, ISA) 是 CPU 能够理解和执行的指令集合。不同 CPU 可能使用不同的指令集,例如:

体系架构 常见 CPU 指令集
x86 / x86-64 Intel, AMD x86, x86-64 (Intel/AMD64)
ARM Apple M1/M2, Qualcomm Snapdragon ARMv8, ARMv9
RISC-V SiFive, 未来自研 CPU RISC-V

指令集决定了汇编语言的语法,同一个操作在不同架构上的写法可能不同。

2. CPU 的基本组成

CPU 的核心部件包括:

  • 寄存器(Registers):存储数据和地址,CPU 直接访问的存储单元

  • 算术逻辑单元(ALU):执行算术和逻辑运算

  • 控制单元(CU):解码指令,控制数据流

  • 总线(Bus):连接 CPU、内存和外设

🔹 x86 寄存器

64 位寄存器 32 位 16 位 8 位 用途
RAX EAX AX AL / AH 累加寄存器(算术运算)
RBX EBX BX BL / BH 基址寄存器
RCX ECX CX CL / CH 计数器(循环/位移)
RDX EDX DX DL / DH 数据寄存器
RSP ESP SP - 栈指针
RBP EBP BP - 栈基址
RSI ESI SI - 源索引寄存器
RDI EDI DI - 目标索引寄存器

💡 64 位模式下,额外提供 R8-R15 寄存器。

3. 指令格式

大多数指令格式如下:

指令 操作数1, 操作数2

  • 操作数可以是 寄存器、内存地址、立即数

  • x86 格式 (AT&T 语法):movl %eax, %ebx源 -> 目标

  • Intel 语法 (常用):mov eax, ebx源 -> 目标

4. x86 常见指令

✅ 数据传输指令

指令 说明
MOV dest, src 复制数据
LEA dest, src 取地址
PUSH src 压栈
POP dest 出栈

示例:

mov eax, 5 ; 把 5 赋值给 EAX

mov ebx, eax ; 把 EAX 的值复制到 EBX

算术指令

指令 说明
ADD dest, src 加法
SUB dest, src 减法
MUL src 乘法(无符号)
IMUL src 乘法(有符号)
DIV src 除法(无符号)
IDIV src 除法(有符号)

示例:

mov eax, 10 add eax, 5 ;

eax = eax + 5 sub eax, 3 ;

eax = eax - 3

逻辑运算

指令 说明
AND dest, src 按位与
OR dest, src 按位或
XOR dest, src 按位异或
NOT dest 取反
SHL dest, n 左移 n 位
SHR dest, n 右移 n 位

示例:

mov eax, 0b1100

and eax, 0b1010 ; 结果 = 0b1000

比较与跳转

指令 说明
CMP op1, op2 比较 op1 和 op2
JE label 等于跳转
JNE label 不等跳转
JG label 大于跳转
JL label 小于跳转
JMP label 无条件跳转

示例:

mov eax, 5

cmp eax, 10

jl less_than_10 ; 如果 eax < 10,跳转

函数调用

指令 说明
CALL func 调用函数
RET 返回

示例:

call my_function

ret

RISC-V 和 ARM 对比

操作 x86 ARM RISC-V
传输 mov eax, ebx mov r0, r1 mv x1, x2
加法 add eax, ebx add r0, r1, r2 add x1, x2, x3
跳转 jmp label b label j label
函数 call func bl func jal x1, func

练习:编写一个简单的汇编程序

section .data

msg db "Hello, world!", 0 ; 字符串

section .text

global _start

_start:

mov edx, 13 ; 输出长度

mov ecx, msg ; 指向字符串

mov ebx, 1 ; 标准输出

mov eax, 4 ; syscall: sys_write

int 0x80 ; 触发系统调用

mov eax, 1 ; syscall: sys_exit

xor ebx, ebx ; 退出代码 0

int 0x80

运行方法

  1. 安装 NASM:sudo apt install nasm

  2. 编译:nasm -f elf32 hello.asm

  3. 生成可执行文件:ld -m elf_i386 -o hello hello.o

  4. 运行:./hello

你可以做什么?

1. 练习写一些基本指令(MOV, ADD, CMP, JMP)

2. 用 gdb 调试一个汇编程序

3. 尝试编写简单的 RISC-V 或 ARM 汇编

4.2 区分并解读ARM 和 RISC-V

1. ARM vs. RISC-V 概述

特性 ARM RISC-V
架构类型 RISC(精简指令集) RISC(精简指令集)
开发模式 封闭商业授权(需付费) 开源(免费使用)
指令集 复杂,历史包袱较重 简洁、模块化
市场占有率 高(广泛用于手机、嵌入式设备) 仍在增长(嵌入式、学术、未来芯片)
性能优化 针对特定硬件优化,功耗低 设计简洁,易扩展
厂商 Apple M1/M2/M3、Qualcomm、Broadcom SiFive、NVIDIA、Intel(未来)
应用领域 移动设备、嵌入式系统、服务器 开源硬件、学术研究、未来服务器

ARM 适合商用市场,RISC-V 更适合研究、定制芯片、国产化 CPU。

2. 指令集对比

(1)寄存器

  • ARM(AArch64,64 位)31 个通用寄存器(X0 - X30) ,加上 SP(栈指针)和 PC(程序计数器)

  • RISC-V(RV64I)32 个通用寄存器(x0 - x31) ,x0 恒为 0x1 用作返回地址,x2 为栈指针。

寄存器 ARM (AArch64) RISC-V (RV64I)
返回值寄存器 X0 x10 (a0)
参数传递寄存器 X0 - X7 x10 - x17 (a0 - a7)
栈指针 SP x2 (sp)
返回地址 X30 (LR) x1 (ra)

(2)基本指令

操作 ARM RISC-V
数据传输 MOV X0, X1 ADD x10, x0, x0 (没有 MOV,用 ADD 实现)
加载/存储 LDR X0, [X1] LW x10, 0(x1)
算术运算 ADD X0, X1, X2 ADD x10, x11, x12
逻辑运算 AND X0, X1, X2 AND x10, x11, x12
比较 & 跳转 CMP X0, X1 B.EQ label BEQ x10, x11, label
函数调用 BL function JAL x1, function
返回 RET JALR x0, x1, 0

💡 区别:

  • ARM 有 MOV 指令,RISC-V 没有 ,需要用 ADD 代替。

  • ARM LDR 直接加载数据,RISC-V 需要 LW(load word)。

  • RISC-V 所有运算都基于寄存器 ,没有 CMP,而是 SUB + 分支指令

3. ARM vs. RISC-V 示例代码

  • ARM (AArch64)

.global _start

_start:

MOV X0, #42 // X0 = 42

MOV X1, #10 // X1 = 10

ADD X2, X0, X1 // X2 = X0 + X1

BL exit // 调用 exit

exit:

MOV X8, #93 // syscall exit

SVC 0

  • RISC-V (RV64I)

.global _start

_start:

LI x10, 42 # x10 = 42

LI x11, 10 # x11 = 10

ADD x12, x10, x11 # x12 = x10 + x11

J exit # 跳转到 exit

exit:

LI a7, 93 # syscall exit

ECALL

主要区别:

  • ARM 直接使用 MOVRISC-V 需要 LI(Load Immediate)。

  • ARM 直接调用 BL 进入函数,RISC-VJAL

  • ARM SVC 0 调用系统调用,RISC-VECALL

4. ARM vs. RISC-V 的发展前景

对比 ARM RISC-V
市场份额 ,占主导 快速增长
开放性 封闭(需授权) 开源(免费)
生态系统 成熟(Android、iOS、嵌入式) 正在完善(未来竞争力强)
功耗优化 非常出色(Apple M 系列) 理论上更好,但仍在优化
使用场景 移动设备、服务器、嵌入式 未来服务器、国产 CPU、物联网

5. 总结

ARM :适用于 商业化市场 ,功耗优化极致,广泛用于手机、嵌入式。

RISC-V完全开源,未来有潜力取代 ARM,但生态系统仍在发展。

如果你想深入学习

  1. ARM 推荐:学习 AArch64 汇编(Apple M1/M2、树莓派)。

  2. RISC-V 推荐:用 QEMU 模拟,或者试试 SiFive 开发板。

4.3 从ARM 和 RISC-V 的基础概念,逐步深入到汇编编程和架构优化

学习路线:

第一阶段:基础概念

1. 计算机架构基础

  • 什么是 RISC(精简指令集)CISC(复杂指令集)

  • ARM 和 RISC-V 的设计理念

  • 指令流水线、寄存器、内存访问方式

2. ARM & RISC-V 指令集

  • 了解寄存器(ARM 的 X0-X30,RISC-V 的 x0-x31)

  • 基本数据传输(MOVLWLDR 等)

  • 算术运算(ADDSUB 等)

  • 逻辑运算(ANDORXOR 等)

  • 分支与跳转(JMPBEQBL 等)

第二阶段:搭建开发环境

1. ARM 开发环境

  • Raspberry Pi (树莓派)或 QEMU 上运行 ARM 代码

  • 使用 GNU as(汇编器) 编写 ARM 汇编

  • ARM 64-bit (AArch64) vs ARM 32-bit (ARMv7)

2. RISC-V 开发环境

  • 使用 QEMU 模拟 RISC-V

  • 使用 riscv-gcc 编写汇编代码

  • 了解 RISC-V 的模块化扩展(RV32IRV64GC

第三阶段:深入汇编编程

1. 编写简单程序

  • "Hello, World!" 汇编实现(ARM & RISC-V)

  • 计算加法、乘法等基本运算

  • 使用 函数调用(CALL/JAL)系统调用(SVC/ECALL)

2. 代码调试

  • GDB(GNU Debugger) 调试 ARM & RISC-V 汇编

  • 学习 寄存器、内存管理、堆栈操作

  • 分析 函数调用栈

第四阶段:深入体系架构

1. ARM 高级特性

  • Thumb 模式(ARM 32-bit 低功耗指令)

  • NEON(SIMD) 向量计算

  • TrustZone 安全架构

2. RISC-V 扩展

  • RV64GC 标准指令集

  • 压缩指令(C-extension)

  • 向量计算(V-extension)

架构原理

RISC(精简指令集) vs. CISC(复杂指令集)

RISC(Reduced Instruction Set Computer)

  • 指令长度固定(如 RISC-V 32 位指令)

  • 只使用 Load/Store 访问内存(所有运算都基于寄存器)

  • 指令集精简,减少硬件复杂性,提升执行效率

  • 流水线执行优化(提高指令并行度)

CISC(Complex Instruction Set Computer)

  • 指令长度可变(如 x86 指令有 1-15 字节)

  • 支持内存直接操作(可对内存数据直接算术运算)

  • 指令复杂,执行周期长(但可以减少指令数量)

  • 适用于高性能计算,但功耗较大

💡 ARM 和 RISC-V 都属于 RISC 体系,相比 x86(CISC)更节能、更易于硬件优化。

ARM 架构

🔹 ARM 设计特点

  • AArch64(ARM 64-bit):现代主流架构(Apple M 系列、Android 手机等)

  • AArch32(ARM 32-bit):老架构(ARMv7,如 Raspberry Pi 1/2)

  • 寄存器:31 个通用寄存器(X0-X30),SP(栈指针),PC(程序计数器)

  • 支持 Thumb 低功耗模式(部分 ARM 处理器)

  • 广泛用于移动设备、嵌入式系统

🔹 ARM 典型指令

  • LDR X0, [X1] // 从内存加载数据到 X0

  • STR X0, [X1] // 将 X0 存入 X1 指向的内存

  • ADD X0, X1, X2 // X0 = X1 + X2

  • BL function // 调用函数

  • RET // 返回

RISC-V 架构

🔹 RISC-V 设计特点

  • 完全开源,可定制(不同于 ARM 的授权模式)

  • 模块化指令集 (基础指令 RV32IRV64I,可扩展 M 乘除、C 压缩、V 向量等)

  • 寄存器:32 个通用寄存器(x0-x31),x0 恒等于 0

  • 适用于芯片设计、学术研究、物联网

🔹 RISC-V 典型指令

  • LW x10, 0(x1) // 从内存加载数据到 x10

  • SW x10, 0(x1) // 将 x10 存入 x1 指向的内存

  • ADD x10, x11, x12 // x10 = x11 + x12

  • JAL x1, function // 调用函数

  • JALR x0, x1, 0 // 返回

ARM vs. RISC-V 对比

特性 ARM RISC-V
架构类型 RISC RISC
授权模式 封闭授权(需付费) 完全开源(免费使用)
指令集 复杂(历史包袱较重) 精简,模块化
功耗优化 极致优化(Apple M1/M2) 理论上更优,但仍需优化
应用场景 移动设备、嵌入式、服务器 芯片研究、物联网、未来服务器

下一步学习

✅ 了解 ARM & RISC-V 指令集 ✅ 研究 寄存器与内存访问 ✅ 搭建 ARM & RISC-V 开发环境(QEMU、Raspberry Pi、SiFive)

4.4 ARM 和 RISC-V 的指令集

1. ARM & RISC-V 指令集概述

对比项 ARM (AArch64, 64-bit) RISC-V (RV64I, 64-bit)
指令长度 固定 32 位(支持 16 位 Thumb 指令) 固定 32 位(支持 16 位压缩指令 C-extension)
寄存器 X0 - X30(31 个通用寄存器) x0 - x31(32 个通用寄存器)
栈指针 SP(Stack Pointer) x2(sp)
程序计数器 PC(Program Counter) PC(Program Counter)
内存访问 LDR/STR(Load/Store) LW/SW(Load Word / Store Word)
跳转/调用 BL(Branch & Link)、RET JAL(Jump and Link)、JALR
运算指令 ADD、SUB、MUL、AND、ORR、EOR ADD、SUB、MUL、AND、OR、XOR
系统调用 SVC(Supervisor Call) ECALL(Environment Call)

2. ARM 指令集

🔹 2.1 数据传输

  • LDR X0, [X1] // 从内存加载数据到 X0

  • STR X0, [X1] // 将 X0 存入 X1 指向的内存

  • MOV X0, X1 // 将 X1 的值复制到 X0

🔹 2.2 算术运算

  • ADD X0, X1, X2 // X0 = X1 + X2

  • SUB X0, X1, X2 // X0 = X1 - X2

  • MUL X0, X1, X2 // X0 = X1 * X2

  • SDIV X0, X1, X2 // X0 = X1 / X2(整数除法)

🔹 2.3 逻辑运算

  • AND X0, X1, X2 // X0 = X1 & X2

  • ORR X0, X1, X2 // X0 = X1 | X2

  • EOR X0, X1, X2 // X0 = X1 ^ X2

  • LSL X0, X1, #3 // X0 = X1 << 3(左移 3 位)

  • LSR X0, X1, #3 // X0 = X1 >> 3(右移 3 位)

🔹 2.4 条件分支

  • CMP X0, X1 // 比较 X0 和 X1

  • B.EQ label // 如果相等,则跳转到 label

  • B.NE label // 如果不相等,则跳转到 label

  • B.GT label // 如果 X0 > X1,则跳转

  • BL function // 调用 function

  • RET // 返回

3. RISC-V 指令集

🔹 3.1 数据传输

  • LW x10, 0(x1) // 从内存加载数据到 x10

  • SW x10, 0(x1) // 将 x10 存入 x1 指向的内存

  • MV x10, x11 // 将 x11 复制到 x10(MOV 在 RISC-V 中是 ADD 的别名)

🔹 3.2 算术运算

  • ADD x10, x11, x12 // x10 = x11 + x12

  • SUB x10, x11, x12 // x10 = x11 - x12

  • MUL x10, x11, x12 // x10 = x11 * x12

  • DIV x10, x11, x12 // x10 = x11 / x12(整数除法)

🔹 3.3 逻辑运算

  • AND x10, x11, x12 // x10 = x11 & x12

  • OR x10, x11, x12 // x10 = x11 | x12

  • XOR x10, x11, x12 // x10 = x11 ^ x12

  • SLL x10, x11, x12 // x10 = x11 << x12(左移)

  • SRL x10, x11, x12 // x10 = x11 >> x12(右移)

🔹 3.4 条件分支

  • BEQ x10, x11, label // 如果 x10 == x11,跳转

  • BNE x10, x11, label // 如果 x10 != x11,跳转

  • BLT x10, x11, label // 如果 x10 < x11,跳转

  • BGE x10, x11, label // 如果 x10 >= x11,跳转

  • JAL x1, function // 调用 function

  • JALR x0, x1, 0 // 返回

4. ARM vs. RISC-V 指令示例

🔹 ARM (AArch64)

.global _start

_start:

MOV X0, #42 // X0 = 42

MOV X1, #10 // X1 = 10

ADD X2, X0, X1 // X2 = X0 + X1

BL exit // 调用 exit

exit:

MOV X8, #93 // syscall exit

SVC 0

🔹 RISC-V (RV64I)

复制代码
.global _start
_start:
    LI x10, 42      # x10 = 42
    LI x11, 10      # x11 = 10
    ADD x12, x10, x11  # x12 = x10 + x11
    J exit          # 跳转到 exit
exit:
    LI a7, 93       # syscall exit
    ECALL

主要区别:

  • ARM 直接使用 MOV 指令,RISC-V 需要 LI(Load Immediate)

  • ARM 直接调用 BL,RISC-V 需要 JAL

  • ARM 使用 SVC 0,RISC-V 使用 ECALL 进行系统调用

4.5 编写 ARM & RISC-V 汇编代码

1. 编写 ARM 汇编代码(AArch64)

🔹 1.1 "Hello, World!"

.global _start

.section .data

message: .asciz "Hello, World!\n"

.section .text

_start:

MOV X0, #1 // 文件描述符 1 (stdout)

ADR X1, message // 消息地址

MOV X2, #14 // 消息长度

MOV X8, #64 // syscall write

SVC 0

MOV X8, #93 // syscall exit

MOV X0, #0 // 退出码 0

SVC 0

说明

  • MOV X0, #1 设置标准输出

  • ADR X1, message 加载字符串地址

  • MOV X8, #64 表示 write 系统调用

  • SVC 0 触发系统调用

1.2 简单的加法

.global _start

_start:

MOV X0, #10 // X0 = 10

MOV X1, #20 // X1 = 20

ADD X2, X0, X1 // X2 = X0 + X1

MOV X8, #93 // syscall exit

MOV X0, #0

SVC 0

说明

  • MOV 指令用于加载立即数

  • ADD X2, X0, X1 计算 X0 + X1

1.3 条件判断

.global _start

_start:

MOV X0, #5

MOV X1, #10

CMP X0, X1

B.GE greater_or_equal

MOV X2, #0 // X0 < X1 时执行

B exit

greater_or_equal:

MOV X2, #1 // X0 >= X1 时执行

exit:

MOV X8, #93

SVC 0

说明

  • CMP X0, X1 进行比较

  • B.GE 进行条件跳转

2. 编写 RISC-V 汇编代码(RV64I)

🔹 2.1 "Hello, World!"

.global _start
.section .data
message: .asciz "Hello, World!\n"

.section .text
_start:
LI a0, 1 # 文件描述符 1 (stdout)
LA a1, message # 加载字符串地址
LI a2, 14 # 消息长度
LI a7, 64 # syscall write
ECALL

LI a7, 93 # syscall exit
LI a0, 0 # 退出码 0
ECALL

说明

  • LI(Load Immediate)用于加载立即数

  • LA(Load Address)用于加载地址

  • ECALL 触发系统调用

2.2 简单的加法

.global _start

_start:

LI x10, 10 # x10 = 10

LI x11, 20 # x11 = 20

ADD x12, x10, x11 # x12 = x10 + x11

LI a7, 93 # syscall exit

ECALL

说明

  • LI 加载数值

  • ADD 执行加法

2.3 条件判断

.global _start

_start:

LI x10, 5

LI x11, 10

BGE x10, x11, greater_or_equal

LI x12, 0 # x10 < x11 时执行

J exit

greater_or_equal:

LI x12, 1 # x10 >= x11 时执行

exit:

LI a7, 93

ECALL

说明

  • BGE x10, x11, label 进行条件跳转

  • J label 无条件跳转

3. 运行汇编代码

🔹 ARM(AArch64)

在 Linux 上安装 GCC 并运行:

aarch64-linux-gnu-as -o program.o program.s

aarch64-linux-gnu-ld -o program program.o

qemu-aarch64 ./program

🔹 RISC-V

安装 riscv64 交叉编译工具:

riscv64-linux-gnu-as -o program.o program.s

riscv64-linux-gnu-ld -o program program.o

qemu-riscv64 ./program

4.6 搭建 ARM & RISC-V 开发环境

1. 运行 ARM 指令

🔹 1.1 编写 ARM 汇编

创建文件 arm_test.s

.global _start

_start:

MOV X0, #42 // X0 = 42

MOV X8, #93 // syscall exit

SVC 0 // 执行系统调用

1.2 编译 & 运行

aarch64-linux-gnu-as -o arm_test.o arm_test.s # 汇编

aarch64-linux-gnu-ld -o arm_test arm_test.o # 链接

qemu-aarch64 ./arm_test # 运行

如果成功,程序会 返回状态码 42 ,可以用 $? 检查:

echo $?

2. 运行 RISC-V 指令

🔹 2.1 编写 RISC-V 汇编

创建文件 riscv_test.s

.global _start

_start:

LI a0, 42 # a0 = 42

LI a7, 93 # syscall exit

ECALL # 执行系统调用

2.2 编译 & 运行

riscv64-linux-gnu-as -o riscv_test.o riscv_test.s # 汇编

riscv64-linux-gnu-ld -o riscv_test riscv_test.o # 链接

qemu-riscv64 ./riscv_test # 运行

同样,可以用 $? 检查返回值:

echo $?

3. 在 QEMU 启动完整 Linux

🔹 3.1 运行 ARM Linux

qemu-aarch64 -L /usr/aarch64-linux-gnu ./arm_test

-L /usr/aarch64-linux-gnu 指定 QEMU 运行所需的 ARM 共享库。

🔹 3.2 运行 RISC-V Linux

qemu-riscv64 -L /usr/riscv64-linux-gnu ./riscv_test

4. 进入 QEMU 交互模式

可以运行 QEMU 并进入 GDB 调试模式

qemu-aarch64 -g 1234 ./arm_test

然后在另一个终端启动 GDB:

gdb-multiarch -q -ex "target remote :1234"

相关推荐
uyeonashi2 分钟前
【C++】从零实现Json-Rpc框架(2)
开发语言·c++·rpc·json
Excuse_lighttime3 分钟前
JAVA阻塞队列
java·开发语言·jvm
啊阿狸不会拉杆5 分钟前
第二十八章:Python可视化图表扩展-和弦图、旭日图、六边形箱图、桑基图和主题流图
开发语言·python
心灵宝贝8 分钟前
openssl-1.0.1e.tar.gz编译安装步骤
linux·运维·服务器
自由鬼9 分钟前
开源免费虚拟化软件PVE功能介绍
运维·服务器·开源·虚拟化
想要打 Acm 的小周同学呀34 分钟前
TCP基础篇(一)
服务器·网络·tcp/ip
green5+11 小时前
LeetCode18四数之和
java·开发语言·算法
啊阿狸不会拉杆1 小时前
第二十五章:Python-pyecharts 库实现 3D 地图绘制
开发语言·python·地图
满怀10151 小时前
Python入门(8):文件
开发语言·python
pk_xz1234561 小时前
完整的Python程序,它能够根据两个Excel表格(假设在同一个Excel文件的不同sheet中)中的历史数据来预测未来G列数字
开发语言·python·excel