汇编总览
Code CIN 提供三条平行的程序输入路径, 它们共用同一套 ISA、同一个汇编器入口、同一种字节码。 无论你写高级语言、PL 关键字风格还是 ARM64 风格汇编, 最终都会被翻译成同构的 (opcode, operands) 指令序列, 交给同一个 CPU 执行。
三条输入路径
| 扩展名 | 路径 | 风格 | 由谁处理 |
|---|---|---|---|
.cin | 高级语言 | 类 C, 函数 / struct / 数组 / 字符串 | codecin/cin.py 的 CINCompiler |
.pl | PL 关键字风格汇编 | set / add / jump_zero 等英文关键字 | codecin/assembler.py |
.asm | 汇编 | 原生助记符 MOV / ADD / CMP, 兼容 ARM64 / RISC-V 写法 | codecin/assembler.py |
.pl 与 .asm 走的是完全相同的代码路径: codecin/cpu.py 的 load_program() 对二者 不做区分, 都由 Assembler.assemble_file() 解析。区别只在于助记符字典:
.asm直接使用Constants.OPCODE_NAME_TO_ENUM中的大写助记符 (MOV、ADDI、B…);.pl使用Constants.PL_KEYWORDS中的小写关键字 (set、add_imm、branch…)。
因为 PL 关键字只是一张映射表, 你甚至可以在同一个文件里混用两种风格:
.text
main:
set x0, 0 ; PL 关键字风格
mov x1, 1 ; ASM 风格
MOV x2, 10 ; 助记符大小写不敏感
loop:
add x0, x1 ; 两种风格共享 ADD
increment x1 ; PL: increment = INC
compare x1, 11 ; PL: compare = CMP
jl loop ; ASM 条件跳转
out x0
halt55最小可运行程序
一个能跑起来的汇编程序至少需要 .text 段。main 标签是约定的入口 (由 load_program() 读取 self.labels.get('main', 0)), 没有 main 时从第 0 条指令开始执行。
; 最小可运行程序: 输出 7 然后停机
.text
main:
mov x0, 7
out x0
out 10 ; 输出字节 10 等于换行
halt7.text 段里的 main: 是标签, halt 是唯一的正常停机方式 (不写 halt 时程序会一直执行到 指令序列末尾后停止, 见 汇编语法参考 的"常见报错与排查")。
统一汇编器入口
两条汇编路径共用 codecin/assembler.py 的 Assembler 类:
| 方法 / 成员 | 作用 |
|---|---|
assemble_file(filename) | 从文件读取并按 #include 预处理后汇编 |
assemble_source(source) | 直接从字符串汇编 (供 CIN 编译器与测试使用) |
self.instructions | 产物: (opcode_name, operands) 列表 |
self.labels | .text 段标签名到指令下标的映射 |
self.data_labels | .data 段标签名到数据地址的映射 |
self.equ | .equ / .set 定义的常量表 |
汇编分两遍完成: 第一遍扫描段声明、.equ、标签与数据指示符, 第二遍才解析指令与操作数, 因此同一文件内的标签可以前向引用, 而 .equ 的值必须在其定义行之前已经确定。
运行命令
最简形式是直接给出程序文件, 由扩展名选择路径:
codecin test_asm.asm # 汇编
codecin basic.cin # 高级语言
codecin prog.pl # PL 关键字风格
codecin prog.bin # 已编译字节码文档中的示例统一加上 --log-level ERROR, 保持输出干净:
codecin test_asm.asm --log-level ERRORSum 1..10 = 55
155常用的相关开关 (完整列表见 codecin --help):
| 开关 | 作用 |
|---|---|
--strict | 严格汇编模式, 校验指令的操作数个数 |
--compile-only | 只编译为 .sdgcc (默认产物), 不执行 |
--disasm | 反汇编 .sdgcc / .bin 字节码并退出 |
--log-level ERROR | 只输出错误, 保持示例输出干净 |
在 Windows PowerShell 中同样直接调用:
codecin test_asm.asm --log-level ERROR与 CIN 的关系
同一 ISA、同一字节码、同一执行引擎是 Code CIN 的核心设计约束:
.cin 高级语言 ──► CINCompiler ──┐
├──► (opcode, operands) 指令序列
.pl PL 关键字 ──► Assembler ───┤ │
.asm 汇编 ──► Assembler ───┘ ├──► UCBC 字节码 .bin
└──► Go 原生引擎 (codecin_run_v2)- 同一 ISA: 112 条指令由
codecin/isa.py的Opcode枚举唯一定义。 - 同一字节码:
.cin与.asm都能编译成同格式的.bin(--compile-only), 并可互相反汇编验证。 - 同一执行引擎: 字节码统一交给 Go 原生引擎整程序执行 (v5.9.0 起 native-only), 语义不会因输入路径而分叉。
CIN 还能在函数体里直接内嵌 PL 关键字风格的 CPU 指令语句 (无逗号), 实现零开销的定点操作:
.text
main:
mov x0, 0
mov x1, 1
loop:
add x0, x1
inc x1
cmp x1, 11
jl loop
out x0
halt三者输出都是 55。内嵌 CPU 指令的 CIN 写法见 内嵌 CPU 指令语句:
function main() -> int {
int i = 0
int total = 0
for (int k = 1; k <= 10; k = k + 1) {
set i i
add i k
add total i
}
println("total = " + total)
return 0
}学习路径
建议按以下顺序阅读:
- 汇编语法参考 —— 注释、段、数据指示符、标签、操作数形式、
.equ表达式与--strict。 - 指令语义参考 —— 112 条指令的分组表与常用指令的独立小节。
- 指令集编码表 —— 由
script/gen_isa_docs.py自动生成的编码表, 与codecin/isa.py同步。 - 寄存器与内存模型 ——
x0–x31、sp/fp/lr/xzr、向量寄存器与栈布局。 - 快速开始 —— 安装、命令行与第一个程序。
从示例文件入手
仓库里的 test_asm.asm 是端到端可运行的权威样例 (循环求和 + 字符串打印 + .data 段 + 间接寻址), examples/asm_constants.asm 演示 .equ 与表达式立即数。两个文件都可以直接用 codecin <文件> 运行。
文档中的旧示例
仓库根目录 README.md 里的部分 PL 示例使用了本 ISA 不存在的 jle / jge 助记符。 Base ISA 的比较跳转只有 JMP / JZ / JNZ / JE / JL / JG, 请以 指令语义参考 为准。