自定义汇编语言(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    # 克隆远程仓库
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"
 

你可能感兴趣的:(unix,git,服务器,开发语言)