- 7
- 5月
在IAR中,编译器会根据函数情况对函数进行控制。但是有时,我们需要对某些函数进行强制内嵌或者强制不内嵌的操作。
如果需要对函数进行强制内嵌的操作,可以在函数上加上
#pragma inline=forced
来进行强制内嵌。
如果想函数不进行内嵌,则可加上
#pragma optimize=no_inline
来进行强制不内嵌。
以上程序对IAR720H有效。其它版本,需要根据相应的帮助来进行。
在IAR中,编译器会根据函数情况对函数进行控制。但是有时,我们需要对某些函数进行强制内嵌或者强制不内嵌的操作。
如果需要对函数进行强制内嵌的操作,可以在函数上加上
#pragma inline=forced
来进行强制内嵌。
如果想函数不进行内嵌,则可加上
#pragma optimize=no_inline
来进行强制不内嵌。
以上程序对IAR720H有效。其它版本,需要根据相应的帮助来进行。
版本是IAR720H
使用了下面一断程序
#define YEAR_DAYS 365
#define FOURYEAR_DAYS (YEAR_DAYS * 4 + 1)
猜猜FOURYEAR_DAYS值是多少?
按照Hanny最初的想法,结果应该是365 * 4 + 1 = 1461。
结果实际预处理的结果却是365 * (4 + 1) = 1825。
Hanny怀疑是宏嵌套的问题,于是又实验了
#define FOURYEAR_DAYS (365 * 4 + 1)
结果,还是1825。
看来,IAR的预处理在乘和加的优先级上,优先计算了加!
多加个括号就可以了。要注意啊!
IAR对局部部变量,一般是采取虚拟寄存器的方式来进行访问。如果是外部堆栈的话,有时它会将SPH,SP的值赋至DPTR中,然后使用DPTR来对堆栈进行操作。
然而,除了将SPH和SP的值赋至DPTR外,它还会做一些动作。
ANL A,#0x03 ; Maks out relevant ESP bits.
ORL A,#(HIGH(sfb(EXT_STACK)) & 0xFC)
MOV DPH,A
其实就是会将堆栈的高6BIT地址强制不可改。具体作用暂时不明。
不过,如果有做一些多BIN的工程时,可就要小心了,需要保证堆栈的高6BIT地址不变,否则可能出一些不可预料的错误。
想用IAR的C语言来该问一下LONG型变量的4个Byte,版本是IAR720H的。
最初,按照最直观的写法,用这种方法来进行访问:
(unsigned char)(num)
(unsigned char)(num>>8)
(unsigned char)(num>>16)
(unsigned char)(num>>24)
编译,查看lst文件。what??这是什么呀!!
居然出现了?UL_SHR。
你还真去右移了呢?
接下来,换用第二种方式:
((unsigned char *)&num)[0]
((unsigned char *)&num)[1]
((unsigned char *)&num)[2]
((unsigned char *)&num)[3]
这下,问题更大了。
什么DPTR都来了。这个更夸张。
差点都想自己写汇编算了。
最后经过了许多实验,总算把方法试出来了。
可以定义以下的宏:
#define BYTE0(n) ((unsigned char)(n))
#define BYTE1(n) ((unsigned char)((n)>>8))
#define BYTE2(n) ((unsigned char)(((unsigned short)((n)>>8))>>8))
#define BYTE3(n) ((unsigned char)(((unsigned short)((n)>>16))>>8))
以后就可以直接用BYTE0 ~ BYTE3来进行LONG型变量的按BYTE来访问了。
IAR嵌汇编真是有些危险,尤其是关于堆栈的操作,经常就被“优化”了。
案例一:多中断程序的入口处有压栈保护操作,结果被优化生子程序来进行调用;
案例二:出口的压出栈操作不一样的,也被优化到一起去了。
IAR中要嵌汇编,千万要把优先级调低!