差異處
這裏顯示兩個版本的差異處。
兩邊的前次修訂版前次修改 下次修改 | 前次修改 | ||
wiki:自动化与科技指导:minecoprocessors:编程规范 [2023/12/08 15:06] – [注释] nikoqw | wiki:自动化与科技指导:minecoprocessors:编程规范 [2023/12/08 16:04] (目前版本) – [CDecl] nikoqw | ||
---|---|---|---|
行 2: | 行 2: | ||
为了能够重复利用现有代码,在代码与代码之间调用,所有程序必须遵守本编程规范。 | 为了能够重复利用现有代码,在代码与代码之间调用,所有程序必须遵守本编程规范。 | ||
- | ===== 汇编语言风格 ===== | + | <wrap cjk-em> |
+ | |||
+ | <wrap cjk-em> | ||
+ | |||
+ | ===== 用户程序约定 ===== | ||
+ | * 用户程序代码必须在所有库函数代码之后。 | ||
+ | * 用户程序必须包含一个 '' | ||
+ | |||
+ | ===== 汇编语言风格规范 | ||
==== 指令 ==== | ==== 指令 ==== | ||
每个指令与其操作数使用一个空格隔开。操作数之间使用一个逗号 + 空格('', | 每个指令与其操作数使用一个空格隔开。操作数之间使用一个逗号 + 空格('', | ||
行 9: | 行 17: | ||
</ | </ | ||
==== 标签 ==== | ==== 标签 ==== | ||
- | 所有标签使用下划线分词。除[[# | + | 所有标签使用下划线分词。除 [[#Calling convention|Calling convention]] 所规定的特殊前后缀外,一律使用小写字母。 |
<code ASM> | <code ASM> | ||
nimshab_miga: | nimshab_miga: | ||
</ | </ | ||
==== 注释 ==== | ==== 注释 ==== | ||
- | 使用一个分号 + 空格 + 正文。 | + | 如果注释为自然语言,使用一个分号 + 空格 + 正文,确保首字母大写,且在单词间换行时使用连字符。 |
- | 如果注释为自然语言,确保首字母大写,且在单词间换行时使用连字符。如果是对应的 C 代码,则首字母小写。 | + | 如果是汇编对应的 C 代码,使用两个分号 + 正文,确保首字母小写。 |
<code ASM> | <code ASM> | ||
- | ; Test running | + | ; Test running |
- | ; -clear reactor | + | ; -uclear |
- | ; out_h_for_whi | + | ; for a while |
- | ; le(0, 5); | + | ;; |
+ | ;;le(0, 5); | ||
MOV c, 0 | MOV c, 0 | ||
MOV d, 5 | MOV d, 5 | ||
- | CALL out_h_for_while | + | CALL out_h_for_while |
</ | </ | ||
行 31: | 行 40: | ||
* 0 1 2 3 分别代表前、后、左、右四个 I/O 口。 | * 0 1 2 3 分别代表前、后、左、右四个 I/O 口。 | ||
- | ===== 函数 ===== | + | ===== 函数规范 |
==== 结构 ==== | ==== 结构 ==== | ||
若函数所遵循的调用约定规定要在函数中通过压栈的方式暂存寄存器状态,则分三块结构编写: | 若函数所遵循的调用约定规定要在函数中通过压栈的方式暂存寄存器状态,则分三块结构编写: | ||
行 41: | 行 50: | ||
遵照如下所示的结构: | 遵照如下所示的结构: | ||
<code ASM> | <code ASM> | ||
- | ; 【FUNC】==== | + | ; 【FUNC】< |
< | < | ||
; Init regs | ; Init regs | ||
行 59: | 行 68: | ||
<code ASM> | <code ASM> | ||
+ | ; 【FUNC】< | ||
< | < | ||
; Init regs | ; Init regs | ||
行 86: | 行 96: | ||
**汇编** | **汇编** | ||
<code ASM> | <code ASM> | ||
- | ; 【FUNC】==== | + | ; 【FUNC】d,c==== |
+ | ; d: b fast_boot | ||
start_machine: | start_machine: | ||
- | ; if(fast_boot) | + | ; Init regs. |
- | CMP pf, 0xff | + | PUSH c |
+ | |||
+ | ; Main logic. | ||
+ | ;; | ||
+ | CMP d, 0 | ||
JZ sm__if_fbot | JZ sm__if_fbot | ||
JMP sm__if_fbot_el | JMP sm__if_fbot_el | ||
- | ; { | + | ;;{ |
sm__if_fbot: | sm__if_fbot: | ||
; 快速启动 逻辑 | ; 快速启动 逻辑 | ||
JMP sm__ps_if_fbot | JMP sm__ps_if_fbot | ||
- | ; } else { | + | ;;} else { |
sm__if_fbot_el: | sm__if_fbot_el: | ||
; 慢速启动 逻辑 | ; 慢速启动 逻辑 | ||
sm__ps_if_fbot: | sm__ps_if_fbot: | ||
- | ; } | + | ;;} |
- | ; 检查启动是否成功 逻辑 | + | ; 通知启动成功 逻辑 |
+ | MOV c, 0x10 | ||
+ | MOV d, 0 | ||
+ | CALL out_h_for_while | ||
+ | |||
+ | ; Exit. | ||
+ | POP c | ||
RET | RET | ||
</ | </ | ||
行 110: | 行 131: | ||
#include < | #include < | ||
- | void start_machine() { | + | void start_machine(bool fast_boot) { |
- | | + | |
if (fast_boot) { | if (fast_boot) { | ||
// 快速启动 | // 快速启动 | ||
行 117: | 行 137: | ||
// 慢速启动 | // 慢速启动 | ||
} | } | ||
- | // 检查启动是否成功 | + | // 通知启动成功 |
+ | out_h_for_while(0, | ||
} | } | ||
</ | </ | ||
行 123: | 行 144: | ||
</ | </ | ||
- | ==== 注释 | + | ==== 如何写参数及返回值说明 ==== |
- | 每个非内部函数(与其他程序共享的函数而非自己使用的函数)都需要具备注释。注释需要按顺序阐明: | + | 函数标记中包含「参数及返回值说明」。它的规则如下: |
+ | |||
+ | 如果函数没有返回用寄存器列表,则使用下面的语法: | ||
+ | |||
+ | <code ASM> | ||
+ | [传参用寄存器列表][, | ||
+ | </ | ||
+ | |||
+ | 如果函数有返回用寄存器列表,则使用下面的语法: | ||
+ | <code ASM> | ||
+ | [传参用寄存器列表], | ||
+ | </ | ||
+ | |||
+ | 如果函数既没有传参用寄存器,也没有内部使用的寄存器和返回用寄存器,则使用下面的语法: | ||
+ | <code ASM> | ||
+ | </ | ||
+ | ==== 文档 | ||
+ | 每个非内部函数(与其他程序共享的函数而非自己使用的函数)都需要具备文档。文档需要按顺序阐明: | ||
- 调用约定,若为 StdCall 则不写。 | - 调用约定,若为 StdCall 则不写。 | ||
- 作用 | - 作用 | ||
行 135: | 行 173: | ||
StdCall, StdCallR, QCall, CDecl | StdCall, StdCallR, QCall, CDecl | ||
+ | |||
+ | '' | ||
==== StdCall ==== | ==== StdCall ==== | ||
行 141: | 行 181: | ||
使用寄存器传参,没有返回值。 | 使用寄存器传参,没有返回值。 | ||
- | 采用 StdCall 的函数必须使用 d c b a 的顺序用寄存器保存参数。 | + | 采用 StdCall 的函数最好使用 d c b a 的顺序用寄存器保存参数。 |
采用 StdCall 的函数不加任何后缀。 | 采用 StdCall 的函数不加任何后缀。 | ||
行 170: | 行 210: | ||
无论调用方使用是否使用了被调用函数内部使用的寄存器,调用方在 CALL 函数前都必须将< | 无论调用方使用是否使用了被调用函数内部使用的寄存器,调用方在 CALL 函数前都必须将< | ||
+ | |||
+ | 被调用的函数在退出前不复原自身使用的寄存器的状态。 | ||
==== CDecl ==== | ==== CDecl ==== | ||
- | “C Declaration”,C 语言的调用约定。本调用约定是为了应对数量较多的参数。 | + | “C declaration”,C 语言的调用约定。本调用约定是为了应对数量较多的参数。 |
使用栈传参,使用寄存器返回值。 | 使用栈传参,使用寄存器返回值。 |