在汇编文件中包含头文件

Ins*_*der 0 assembly gcc gnu gnu-assembler att

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

下面是我的main.S文件

#include "common.h"
BEGIN
    mov $0x0E40, %ax
    int $0x10
    hlt
Run Code Online (Sandbox Code Playgroud)

以下是我的common.h文件:

.macro BEGIN
    LOCAL after_locals
    .code16
    cli
    ljmp $0, $1f
    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
Run Code Online (Sandbox Code Playgroud)

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

$ as --32 -o main.o main.S
main.S: Assembler messages:
main.S:2: Error: no such instruction: `begin'
Run Code Online (Sandbox Code Playgroud)

我缺少什么?我做了一些研究并在 SO 中得到了这个答案,但这没有帮助。请帮忙。

ema*_*uts 6

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

as只是一个汇编程序,它将汇编源代码转换为目标代码。它不运行应该扩展的 C 预处理器#include

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

你可以做什么:

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

注意:在情况 1 中,通过添加包含搜索路径-I path可能无法按预期工作:编译器驱动程序(在本例中)仅在知道它是 GNU 汇编器时gcc才会添加到汇编器的命令行。-I path当编译器通过配置标志配置时,您可以知道这一点--with-gnu-as

注意:类似的情况也适用于链接。您可能不想(ld手动)调用链接器,除非您正在制作静态可执行文件或平面二进制文件;如果您要制作在主机系统上运行的普通可执行文件,请使用gcc或代替。g++它将添加许多链接所需的选项,例如多库路径、搜索路径等,您不想手动调整这些选项。

int $0x10不过,这是一个 16 位 BIOS 调用,它无法在现代主流操作系统下工作,只能在 DOS 或旧版 BIOS 引导加载程序下工作。)