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 内联汇编的主要内容,如果未能解决你的问题,请参考以下文章

GCC内联汇编常见陷阱

VC内联汇编和GCC内联汇编的语法区别

操作系统学习之GCC内联汇编

用于复数乘法的汇编代码/AVX 指令。 (GCC 内联汇编)

[翻译] GCC 内联汇编 HOWTO

似乎无法将 %ES 添加到clobberlist(内联汇编,GCC)