函数¶
函数分为普通函数和中断函数。普通函数和中断函数均可以使用纯汇编来编写,即纯汇编函数,使用关键字__asm
修饰即可。
普通函数¶
参数:仅支持无参数或一个参数,且参数的数据位宽不能超过8比特(函数定义时参数必须定义为8比特);
返回值:仅支持无返回值或返回值得数据位宽不能超过8比特(函数定义时返回值必须定义为8比特)。
因为函数参数和返回值得传递都仅通过累加器A
进行。
1 2 3 4 5 6 7 8 9 10 11 12 | _Bool fn(uint8_t arg) { ... } void main() { ... while(1){ ... } } |
普通函数调用时,PCL
和PCH
依次自动入栈;普通函数返回时,PCH
和PCL
依次自动出栈。
stack
| |
...
| |
| |
| PCH | 1
| PCL | 0
+-----+
中断函数¶
中断函数通过__interrupt
关键字指定,且一个程序最多仅有一个中断函数。
注意
中断函数不应该有参数和返回值。
中断函数的名字无关紧要,只要不与其他函数/变量等冲突即可。
1 2 3 4 | void isr() __interrupt { ... } |
发生中断时,ACC
,STATUS
,PCL
和PCH
依次自动入栈,然后自动跳转到中断函数;中断返回时,PCH
,PCL
,STATUS
和ACC
依次自动出栈,程序依据PCH
和PCL
自动跳转到发生中断位置继续执行。
stack
| |
...
| |
| |
| PCH | 3
| PCL | 2
| STATUS | 1
| ACC | 0
+---------+
纯汇编函数¶
使用关键字__asm
修饰函数即可得到纯汇编函数,要求__asm
放在参数表之后,紧挨着函数体。
注意
纯汇编函数中无法定义任何变量,且编译器不会帮助添加ret
/reti
指令。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | //纯汇编中断函数 void isr() __interrupt __asm { ... reti } //纯汇编普通函数 uint8_t bcd_inc(uint8_t val) __asm{ add A, #1; da A; ret; } void main() __asm { } |