【问题标题】:#include header with C declarations in an assembly file without errors?#include 带有 C 声明的头文件在汇编文件中没有错误?
【发布时间】:2011-06-23 03:07:02
【问题描述】:

我有一个汇编文件 (asm.S),它需要一个常量 #define'd 在 C 头文件 (c_decls.h) 中。除了我想要的 #define 之外,头文件还包含 C 函数声明。不幸的是,gcc barfs 在尝试编译程序集文件时。例如,

c_decls.h

#ifndef __c_decls_h__
#define __c_decls_h__

#define I_NEED_THIS 0xBEEF
int foo(int bar);

#endif

asm.S

#include "c_decls.h"

.globl main
main:
    pushl %ebp
    movl %esp, %ebp
    movl $I_NEED_THIS, %eax
    leave
    ret

输出

> gcc -m32 asm.S
c_decls.h:汇编程序消息:
c_decls.h:6:错误:表达式后出现垃圾 '(int bar)'
c_decls.h:6: 错误:'int' 的后缀或操作数无效

有没有办法#include 在汇编文件中包含函数声明的 C 头文件? (更改标题或移动/重新定义#define 不是一种选择。)

【问题讨论】:

  • (更改标题或移动/重新定义#define 不是一个选项。)看到您取消了最合理的选项的资格,我会说您不走运。 :-)
  • 考虑到标头正在调用未定义的行为(通过使用以双下划线开头的名称作为其多重包含保护),我认为您应该重新考虑不更改它的要求。 :-)

标签: c gcc assembly include x86


【解决方案1】:

使用cpp-dM 选项仅从头文件中获取#defines,并包含该文件。

cpp -dM c_decls.h > bare_c_decls.h

现在在您的 .S 文件中包含 bare_c_decls.h。如果您无法更改 .S 文件中的#include,请在另一个目录中生成裸头文件,然后将该包含路径放在编译器/汇编器命令行中,放在其他所有内容之前。

最后,您可以将这一切封装在一个 makefile 中,这样您的“裸”头文件就会自动生成。

【讨论】:

  • 简单的-dM 不适合我。它什么也不返回。 -E -dM 转储所有定义,包括在标题中定义的定义。列表中有超过 700 个定义。
  • 你用的是什么版本的cpp? (注意问题与 gcc 有关)
  • 这是 GNU GCC,arm-none-eabi-g++ (GNU Tools for ARM Embedded Processors) 4.9.3 20150529 (release)
  • @user3124812:你可能跑的是gcc -dM而不是cpp -dM。您应该gcc -E -dM 与您通常使用的所有其他编译选项一起使用,以确保标头中的所有#ifdefs 都获得相同的预定义宏。 (例如,也许您在标头中有#ifdef __AVX__,如果在x86 目标上使用-mavx 与不使用,则定义不同的东西。)所以我建议不要直接使用cpp
【解决方案2】:

这很简单: 在您的 .S 文件中使用

#define __ASSEMBLY__

在你的 .C 文件中使用

#undef __ASSEMBLY__

然后在.h文件中放置条件

       #ifdef __ASSEMBLY__
                  // here declarations only for assembler
       #else
                  // here only for C
       #endif
                  // and here - defines suitable for both

【讨论】:

  • 标头应该包含在“C”中,如 include、#include my_defs.h,而不是像 .include my_defs.h 的“ASM”。在最后一种情况下,#ifdef#else#endif 将被 asm 解析器忽略。只是偶然发现这个......
  • gcc foo.S 已经将 __ASSEMBLER__ 预定义为 1。因此您可以使用 #ifndef __ASSEMBLER__ 保护所有仅 C 语言的内容
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-30
  • 2021-11-24
  • 1970-01-01
  • 1970-01-01
  • 2011-01-30
相关资源
最近更新 更多