• 7
  • 5月

在IAR中,编译器会根据函数情况对函数进行控制。但是有时,我们需要对某些函数进行强制内嵌或者强制不内嵌的操作。

如果需要对函数进行强制内嵌的操作,可以在函数上加上
#pragma inline=forced 来进行强制内嵌。

如果想函数不进行内嵌,则可加上
#pragma optimize=no_inline 来进行强制不内嵌。

以上程序对IAR720H有效。其它版本,需要根据相应的帮助来进行。

  • 16
  • 12月

版本是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的预处理在乘和加的优先级上,优先计算了加!

多加个括号就可以了。要注意啊!

  • 29
  • 9月

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地址不变,否则可能出一些不可预料的错误。

  • 29
  • 6月

想用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来访问了。

  • 24
  • 8月

IAR嵌汇编真是有些危险,尤其是关于堆栈的操作,经常就被“优化”了。

案例一:多中断程序的入口处有压栈保护操作,结果被优化生子程序来进行调用;

案例二:出口的压出栈操作不一样的,也被优化到一起去了。

IAR中要嵌汇编,千万要把优先级调低!