IAR EWAR 内联汇编 Error[Og010], Error [Og005], Error [Og006]

Error [Og005] + [Og006] when using inline assembler

 

EW targets: 430, ARM, AVR
EW component: C/C++ compiler
Last update: April 3, 2013

Problem:

When compiling a project with the IAR Embedded Workbench AVR v 6.12 the following errors might appear:

Error[Og005]: Unknown symbol in inline assembly:

Error[Og006]: Syntax error in inline assembly: "Error[54]: Expression can not be forward"

Solution:

Labels must be referred in the same assembler statement as they are declared.

Use multiline inline assembler (with row breaks \n) to solve this.

Example:

asm( "st     -Y,   R20    \n"
     "spmloop:            \n"
     "lN      R20, 0x37   \n"
     "SBRC    R20, 0      \n"
     "RJMP    spmloop     \n"
     "OUT     0x37,R25    \n"
     "SPM                 \n"
     "LD       R20,Y+     \n");

The behavior was not correct in earlier versions of the compiler platform.

The new release uses a new internal compiler platform which is a bit more strict. 

For the 5.5x and later versions of their compiler, IAR changed the rules for inline assembly such that you can no longer do things like this:

asm("foobar:");
asm("MOV R1, R2");
asm("JMP foobar");

You get an error message like

unknown symbol in inline assembly

The fix will be to tidy up the parts of the WISP firmware that have asm statements referencing labels created in other asm statements.

Where possible, collapse runs of asm statements into one. The above would become:

// oh yeah, and use volatile
asm volatile ("foobar      \n\t" 
              "MOV R1, R2  \n\t"
              "JMP foobar");

 

I've tested a patch that is backward compatible with IAR 5.4x and will merge it shortly.

The patch for IAR 5.5x is ready; check out the iar550 branch.

I'm trying to get someone to test that branch against IAR 5.4x; then I'll merge the patch into master.

I got an error with both the volatile keyword and the label using the kickstarter version of IAR (5.52).

This code compiles correctly,

asm(
"foobar:\n\t"
"MOV R1, R2\n\t"
"JMP foobar"
);

 

Note the addition of the colon.

Volatile still causes an error.

Also not that if we wanted to have code before the label,

we would have to make sure the label is on the left margin:

asm(
"ADD R1, R2 \n"
"foobar: \n\t"
"MOV R1, R2 \n\t"
"JMP foobar"
);

or else IAR doesn't recognize it as a label.

Thanks for those extra details.

You are right that volatile is a no-no and

that labels need special formatting (left justification and trailing colon);

my original suggestion in the first comment was incorrect.

I am about to merge the iar550 branch into master;

it already incorporates these corrections.

 

“Inline assembler instruction does not have a unique size” ARM Thumb-2 IAR

I am having a problem with inline assembly with the IAR compiler for ARM, Cortex-M4.

Here is a simple example of my problem; put the following code in a file, say, named test.c

复制代码
void irqrestore(int flags)
{
  asm volatile(
      "tst    %0, #1\n"
      "bne    1f\n"
      "cpsie  i\n"
      "1:\n"
      :
      : "r" (flags)
      : "memory");
}
复制代码

Now try compiling with IAR compiler:

 

复制代码
$ iccarm --thumb test.c

   IAR ANSI C/C++ Compiler V6.40.2.53884/W32 for ARM
   Copyright 1999-2012 IAR Systems AB.

    asm volatile(
    ^
"C:\home\NuttX\nuttx\test.c",6  Error[Og010]: Inline assembler instruction
          does not have a unique size: "        bne    ?1_0"

Errors: 1
Warnings: none
复制代码

 

Any ideas what is going wrong?

If I change the "bne 1f\n" to "bne 1\n", it compiles fine, but I'm not sure if it is correct.

Answer: From IAR, I was told (and have confirmed) that the following is the correct syntax:

 "bne.n  1f\n"

Or in context:

复制代码
void irqrestore(int flags)
{
  asm volatile(
      "tst    %0, #1\n"
      "bne.n    1f\n"
      "cpsie  i\n"
      "1:\n"
      :
      : "r" (flags)
      : "memory");
}
复制代码

 

So, the IAR compiler's inline assembler is unable to determine the branch length.

gcc-4.8 handles this withgcc -mthumb -O3 -c foo.c -o foo.o (and other options).

There is no need to specify the specific branch type. 

 

posted @   IAmAProgrammer  阅读(2602)  评论(0编辑  收藏  举报
(评论功能已被禁用)
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
历史上的今天:
2014-07-01 STM32 DFU -- Device Firmware Upgrade
点击右上角即可分享
微信分享提示