【问题标题】:Need help passing defined C constants to asm instruction需要帮助将定义的 C 常量传递给 asm 指令
【发布时间】:2022-01-22 23:32:03
【问题描述】:

我在 ATmega 微控制器的 C 程序中有以下代码:

define sbi(port,bit) asm("SBI " #port "," #bit)
[...]
sbi(PORTB,1);

问题是编译器在处理汇编代码时无法识别 PORTB,尽管它已在包含的头文件中定义。有没有办法告诉预编译器将 PORTB (0x1b) 的定义值放在 ASM 指令中而不是文字文本 PORTB 中?当我像这样手动执行此操作时,汇编指令可以正常工作:

sbi(0x1b,1);

但出于显而易见的原因,我希望能够在我的 C 代码中使用 PORTB 和其他定义的名称。

请注意,我只将这个 ASM 宏用于定义的常量,而不是变量,所以我不需要任何花哨的东西来连接我的 ASM 宏和我的 C 代码。我只需要预处理器将 ASM 字符串中的 PORTB 替换为 0x1b。

【问题讨论】:

  • 您可能正在使用 GCC,但是,当询问有关编译器特定功能(如 asm)的问题时,您应该始终指定您正在使用的编译器。
  • 参见manual,尤其是底部段落:“如果你想字符串化宏参数扩展的结果,你必须使用两级宏。” i> TL;DR:创建一个#define str(x) #x 然后使用asm("SBI " str(port) "," #bit)
  • 我目前正在使用 Microchip Studio 附带的 XC8 C 编译器。但是,我没有嫁给这个编译器(这只是默认值)。如果结果更好,我可以切换到 GCC。

标签: c assembly macros microcontroller preprocessor


【解决方案1】:

您通常不应使用字符串化(宏 # 运算符)为 asm 构造构造字符串。相反,请使用extended asm syntax

要将操作数放入汇编指令中,请将该语法与constraints 一起使用,以告诉编译器如何将操作数提供给指令。对于立即数操作数,使用i:

asm("SBI %[port], %[bit]"
    : // Output operands would be here.
    : // Input operands are here.
        [port] "i" (PORT),
        [bit]  "i" (1)
);

指令字符串中的%[port] 替换为名为@9​​87654329@ 的操作数。稍后操作数列表中的[port] 表示该操作数的名称是port。当然这匹配 PORT 除了大小写,但你可以使用其他名称。

"i" 表示使用立即操作数,该操作数必须具有编译时常量值。

(PORT) 中的PORT 是一个表达式,它给出了用于操作数的值。例如,您也可以使用(PORT+1)

1 操作数可以是硬编码的,但上面显示了如何保持它的灵活性。

对于带有i 的默认立即操作数,GCC 和Clang 包括在汇编代码中标记立即操作数的标点符号,例如某些汇编程序中的$。如果由于某种原因这是一个问题,您可以使用%c[port] 而不是%[port] 来获取裸操作数,然后手动插入#,如下所示:

asm("SBI #%c[port], #%c[bit]"
    : // Output operands would be here.
    : // Input operands are here.
        [port] "i" (PORT),
        [bit]  "i" (1)
);

【讨论】:

  • 我试过这个,但我得到以下错误:宏“asm”传递了 2 个参数,但只需要 1 个。我目前正在使用 Microchip Studio 附带的 XC8 C 编译器。
  • @Michael:您是否在宏之外尝试过这种 asm 语法以查看它是否可以编译,如果可以编译到什么 asm?如果没问题,那就担心把它变成一个宏(全部放在一行上可能是最简单的,或者使用 \ 行继续。)
  • 我终于能够为我的编译器切换到 GCC 并将其配置为从本机 C 代码自动生成 SBI 和 CBI 指令。我还在学习这个 Microchip Studio 软件(我以前在 Linux 机器上进行所有编程),但现在编译器给了我想要的东西,我不再需要插入自己的汇编代码。不过,我仍然感谢您的帮助,非常感谢!
猜你喜欢
  • 2018-11-15
  • 1970-01-01
  • 2016-08-07
  • 2012-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多