最近移植了一个UCOSII到STM8L,先从编译器谈起。
由于IAR与VC++很像,所以直接就选用了它。
1. 函数参数传递
了解到它用了16个虚拟寄存器(也可以配置成12个)作为局部变量和函数参数传递。地址从0x00~0x0F。从MAP文件中可以看到。注意0地址是RAM的,所以函数中对指针的判断要特别注意。
从调试时反汇编的代码可以看到,C函数调用开始前都需要调用系统的一些函数用于保存参数,但在汇编里的函数就必须自己保存。比如中断回调函数:
汇编:
PUBLIC _interrupt_29 //UART_TXE irq
SECTION `.far_func.text`:CODE:NOROOT(0)
_interrupt_29: //vector number on datasheet + 2, don't ask me why. zhw
SAVE_VREGS //这个非常重要,由于有C函数调用,编译器会用到VREGS
CALLF UART_TxEmptyIrqHandler
RESTORE_VREGS
IRET
其中宏:
SAVE_VREGS MACRO
push s:?b0
push s:?b1
push s:?b2
push s:?b3
push s:?b4
push s:?b5
push s:?b6
push s:?b7
push s:?b8
push s:?b9
push s:?b10
push s:?b11
push s:?b12
push s:?b13
push s:?b14
push s:?b15
ENDM
RESTORE_VREGS MACRO
pop s:?b15
pop s:?b14
pop s:?b13
pop s:?b12
pop s:?b11
pop s:?b10
pop s:?b9
pop s:?b8
pop s:?b7
pop s:?b6
pop s:?b5
pop s:?b4
pop s:?b3
pop s:?b2
pop s:?b1
pop s:?b0
ENDM
C函数:
#pragma vector = 29
__interrupt void Irq_UARTTxHandler ( void )
{
UART_TxEmptyIrqHandler();
}
看起来C代码简洁,但实际从实际效率来看,汇编的效率更好。
2. 环境配置
主要是配置你选用的芯片型号。另外还有系统堆栈大小和堆的大小。根据实际配置可节省RAM空间。如果要编译库(如FWLIB)也是在Options里面配置。