当前文档版本为 v0.0.0,您可以访问当前页面的 开发中 版本以获取最近可能的更新。

编写汇编程序

汇编程序必须有一个入口段(指定入口地址的段)。

汇编语句

汇编程序文件是由汇编语句组成,这些语句包括控制语句、指令语句等等。例如:

        cseg    at 0x000    //代码段定义
        jmp     $           //汇编指令

汇编程序的每一行只能包含一条语句/指令。一条指令也仅只能出现在一行中,多行语句是不允许的。

汇编程序语句不区分列。语句可以从一行的任何列开始。文档中的示例使用的缩进是为了程序的清晰性,汇编器对此并没有限制。唯一的例外是macro宏参数和指令操作数必须与宏名或者指令名至少分割一个空格。

注释

注释是您可以在程序中包含的文本,用于识别和解释程序。汇编器在编译时会忽略注释,注释不会影响对象文件的生成。

汇编程序的任何地方都可以包含注释。PANCHIP RISC汇编器支持三种注释方式:兼容C语言的单行和多行注释,以及以分号;开头的单行注释。

/*这是一个多
行注释*/

//这是一个单行注释
;这是一个单行注释

        cseg        //这是一个单行注释
        jmp     $   ;这是一个单行注释

不建议使用;单行注释。

符号

符号包括标号(LABEL),bytebit定义的名字。

特殊的汇编符号

PANCHIP RISC汇编仅包含两个特殊符号:

符号

说明

A/a

代表累加器,它与许多汇编指令一起使用

$

代表当前指令地址,链接时会被计算出实际值

        cseg
delay:  set     A       //A = 0xFF
        dsz     A       //A = A - 1, 如果A为0则跳过下一条指令
        jmp     $ - 1   //跳转到上一条指令
        ret             //子程序返回

立即数

立即数时一个数字表达式,作为及其语言指令的一部分进行编码。立即数数值在指令中字面上用来改变寄存器或者存储器中的内容。使用井号#开始,后跟常数表达式的形式表达立即数。

        cseg
        mov     A, #0x56    //立即数0x56加载到累加器A
        ...

内存访问

内存访问指读写寄存器和RAM空间。

PANCHIP RISC汇编指令仅有直接内存访问指令。直接访问的内存地址,直接编码到机器码中。

间接内存访问由具体芯片实现,一般通过一个地址寄存器和一个数据寄存器组成一个间接内存访问接口来完成。将需要读写的寄存器或者内存的地址写入接口地址寄存器,然后通过接口的数据寄存器即可间接读取地址寄存器对应的寄存器或者内存。

表达式和操作数

操作数可以是数字常量、符号名称、表达式……

运算符用于组合和比较汇编程序中的操作数。运算符不是汇编语言指令,不会生成汇编代码,运算符只能进行已知值的计算。

表达式是数字、符号和运算符的组合。预处理指令中的表达式结果是有符号数,汇编指令中的表达式结果是无符号数。表达式是在编译时计算的,因此可以用于计算事先难以确定的值。

数字

数字仅支持十六进制和十进制形式。

进制

前缀

后缀

合法字符

示例

16

H,h

0-9,A-F,a-f

0AFH 23h 5H 0ah

16

0x,0X

0-9,A-F,a-f

0xAF 0X23 0x5 0x0A

10

0-9

12 255 89 123

字符

与C语言的字符兼容,编译时会被翻译为数字,数字值为字符的ASCII值。

        mov     A, #':'     //A = 0x3A
        ...
        mov     A, #' '     //A = 0x20
        ...
        mov     A, #'\n'    //A = 0x0A
        ...

运算符

运算符

描述

实例

defined

仅用于预处理条件指令,测试标号是否存在,存在则为真(真为1,假为0)

defined HELLO
defined(WORLD)

一元+

正号

+5

一元-

负号

-6

!

逻辑非运算符,用来逆转操作数的逻辑状态,如果条件为真则逻辑非运算符将使其为假(真为1,假为0)

!0

~

取反运算符,按二进制位进行”取反”运算

~5

*

将两个操作数相乘

4 * 8

/

分子除以分母

3 / 2

%

取模运算符,整除后的余数

9 % 7

+

将两个操作数相加

2 + 3

-

从第一个操作数中减去第二个操作数

9 - 7

<<

二进制左移运算符,将一个运算对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补0)

1 << 3

>>

二进制右移运算符,将一个数的各二进制位全部右移若干位,正数左补0,负数左补1,右边丢弃

8 >> 2

<

检查左操作数的值是否小于右操作数的值,如果是则条件为真(真为1,假为0)

1 < 2

<=

检查左操作数的值是否小于或等于右操作数的值,如果是则条件为真(真为1,假为0)

2 <= 3

>

检查左操作数的值是否大于右操作数的值,如果是则条件为真(真为1,假为0)

3 > 4

>=

检查左操作数的值是否大于或等于右操作数的值,如果是则条件为真(真为1,假为0)

4 >= 5

==

检查两个操作数的值是否相等,如果相等则条件为真(真为1,假为0)

5 == 5

!=

检查两个操作数的值是否相等,如果不相等则条件为真(真为1,假为0)

7 == 8

&

按位与操作,按二进制位进行”与”运算

3 & 2

^

异或运算符,按二进制位进行”异或”运算

6 ^ 5

|

按位或运算符,按二进制位进行”或”运算

8 | 7

&&

称为逻辑与运算符,如果两个操作数都非零,则条件为真(真为1,假为0)

1 && 5

||

称为逻辑或运算符,如果两个操作数中有任意一个非零,则条件为真(真为1,假为0)

0 || 8

运算符优先级(从高到低)如下表:

类别

运算符

结合性

一元

defined + - ! ~

从右到左

乘除

* / %

从左到右

加减

+ -

从左到右

移位

<< >>

从左到右

关系

< <= > >=

从左到右

相等

== !=

从左到右

位与

&

从左到右

位异或

^

从左到右

位或

|

从左到右

逻辑与

&&

从左到右

逻辑或

||

从左到右