在汇编文件中包含头文件

Including header file in assembly file

我试图将包含宏的头文件包含到我的主程序集文件中,但编译失败。

下面是我的main.S文件

#include "common.h"
BEGIN
    mov [=10=]x0E40, %ax
    int [=10=]x10
    hlt

下面是我的 common.h 文件:

.macro BEGIN
    LOCAL after_locals
    .code16
    cli
    ljmp [=11=], f
    1:
    xor %ax, %ax
    /* We must zero %ds for any data access. */
    mov %ax, %ds
    mov %ax, %es
    mov %ax, %fs
    mov %ax, %gs
    mov %ax, %bp
    /* Automatically disables interrupts until the end of the next instruction. */
    mov %ax, %ss
    /* We should set SP because BIOS calls may depend on that. TODO confirm. */
    mov %bp, %sp
    /* Store the initial dl to load stage 2 later on. */
    mov %dl, initial_dl
    jmp after_locals
    initial_dl: .byte 0
after_locals:
.endm

两个文件都在同一目录中。当我进行编译时:

$ as --32 -o main.o main.S
main.S: Assembler messages:
main.S:2: Error: no such instruction: `begin'

我错过了什么?我做了一些研究并在 SO 中得到了 ,但它没有帮助。请帮忙。

$ as --32 -o main.o main.S

as 只是一个 assembler,它将汇编源代码转换为目标代码。它不 运行 应该扩展 #include.

的 C 预处理器

# 是 x86 的 GAS 语法中的注释字符,因此如果该行被 assembler 看到而不是被 CPP 替换,则该行被视为注释)

你能做什么:

  1. 使用gcc到assemble,加上适当的文件后缀(.S.sx),它会运行在[=72之前的C预处理器=]宁assembler。
    • 添加 -v 以查看 gcc 调用了哪些命令。
    • 如果您的来源有不同的后缀,您可以 -x assembler-with-cpp source.asm
    • 如果要查看预处理后的中间结果,请添加-save-temps。这将使用预处理后的源写入一个 .s 文件。
    • 如果您想将命令行选项传递给 as,您可以例如 -Wa,--32。但是,在本例中,最好使用编译器驱动程序理解的选项,如 -m32-m16。驱动程序知道这些选项,例如,它还会在链接时提供适当的选项,前提是您使用 gcc -m32 ... 进行链接,如下所述。
  2. 使用 .include assembler 指令,它由 assembler 本身处理,而不是 C 预处理器。

注意: 在情况 1 中,通过 -I path 添加包含搜索路径可能无法按预期工作:编译器驱动程序(gcc 在这个case) 将仅在 assembler 的命令行中添加 -I path 如果它知道它是 GNU assembler。当编译器由配置标志 --with-gnu-as.

配置时,您可以知道这一点

注意:链接也类似。您可能不想调用链接器(手动调用 ld),除非您正在制作静态可执行文件或平面二进制文件;如果您要在主机系统上为 运行 创建普通可执行文件,请改用 gccg++。它将添加链接所需的许多选项,如 multilib 路径、搜索路径等,您不想手动 fiddle。

(int [=34=]x10 是一个 16 位的 BIOS 调用,但它在现代主流 OS 下不起作用,只能在 DOS 或遗留 BIOS 引导程序。)

如果您的头文件只是汇编,则在 main.S 中包含 .include "file" 指令。但是这种做法会将代码插入到它包含的位置。