GCC 内联汇编到 IAR 内联汇编
Posted
技术标签:
【中文标题】GCC 内联汇编到 IAR 内联汇编【英文标题】:GCC Inline Assembly to IAR Inline Assembly 【发布时间】:2012-10-20 20:14:22 【问题描述】:我正在尝试将 BeRTOS 用于 Texas Instruments Stellaris Cortex-M3。我的工作环境是 IAR。为适应 IAR 和我正在使用的特定 uC 进行了许多细微的更改,但我有一个似乎无法解决的问题……坦率地说,这有点超出我的想象。
这段代码:
1 void NAKED lm3s_busyWait(unsigned long iterations)
2
3 register uint32_t __n __asm("r0") = iterations;
4
5 __asm volatile (
6 "1: subs r0, #1\n\t"
7 "bne 1b\n\t"
8 "bx lr\n\t"
9 : : "r"(__n) : "memory", "cc");
10
11
...正在生成一些错误和警告。
错误:应为“;” -----> 第 3 行
错误:应为“(” -----> 第 5 行
错误:预期为“)” -----> 第 9 行
警告:变量“__n”已声明但从未引用 -----> 第 3 行
有什么建议吗?
【问题讨论】:
考虑看看这个。它特别指出它不适用于 Cortex 内核,但它确实提供了“不引用特定寄存器”之类的功能...supp.iar.com/Support/?note=86655 更高版本的 IAR 工具支持 GCC 样式的内联汇编。我认为没有办法显式使用 r0,但语法允许您让编译器为您选择一个寄存器。有关详细信息,请参阅 IAR 编译器手册。 【参考方案1】:我很确定 IAR 的编译器不支持内联汇编。至少当我在使用 IAR 的工具时需要在那个级别上做一些事情时,我总是使用一个实际的单独的汇编语言源文件。
您发布的代码看起来或多或少等同于以下 C 代码:
void lm3s_busyWait( unsigned long iterations)
register volatile unsigned long n = iterations;
while (--n)
/* do nothing */
您也许可以使用它来代替您的版本,但速度会慢一些。这是否重要取决于您使用它的目的。编译器通常不会将volatile
放在寄存器中,因此该函数可能会访问内存位置,而不是递减寄存器。
以下是一个小型 ARM 汇编函数,您可以将其放入名为 lm3s_busyWait.s
的文件中,并将其添加到您的 IAR 项目中。它应该与您使用 GCC 的内联汇编的版本完全相同:
/* C prototype:
*
* void lm3s_busyWait( unsigned long iterations);
*
*/
PUBLIC lm3s_busyWait
SECTION .text:CODE:NOROOT(4)
THUMB
lm3s_busyWait:
subs r0, #1
bne lm3s_busyWait
bx lr
end
【讨论】:
IAR 编译器多年来一直支持简单形式的内联汇编,后来的版本支持 gcc 风格的内联汇编,允许代码指定输入和输出寄存器。 @Lindydancer:感谢您的指点 - 在发布我的答案之前,我已经在 IAR (EWARM 6.1) 中查找了一些关于内联汇编的信息,但仍然错过了这些信息(它在“第 1 部分:使用build tools"/"Assembler language interface",而且信息很简陋)。我仍然没有看到有关 gcc 样式内联汇编的信息,但我只有 6.1,当前版本最高为 6.4。以上是关于GCC 内联汇编到 IAR 内联汇编的主要内容,如果未能解决你的问题,请参考以下文章