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 中得到了这个答案,但这没有帮助。请帮忙。
$ as --32 -o main.o main.S
as只是一个汇编程序,它将汇编源代码转换为目标代码。它不运行应该扩展的 C 预处理器#include。
(#是 x86 的 GAS 语法中的注释字符,因此如果汇编器看到该行而不是被 CPP 替换,则该行将被视为注释)
你可以做什么:
gcc汇编,带有适当的文件后缀(.S或.sx),它将在运行汇编程序之前运行 C 预处理器。
-v以查看正在调用哪些命令gcc。-x assembler-with-cpp source.asm.-save-temps. 这将写入一个.s包含预处理源的文件。as,您可以例如-Wa,--32。但是,最好使用编译器驱动程序可以理解的选项,例如-m32或-m16在当前情况下。驱动程序知道这些选项,例如,如果您按照gcc -m32 ...如下所述进行链接,它也会在链接时提供适当的选项。.include由汇编器本身而不是 C 预处理器处理的汇编器指令。注意:在情况 1 中,通过添加包含搜索路径-I path可能无法按预期工作:编译器驱动程序(在本例中)仅在知道它是 GNU 汇编器时gcc才会添加到汇编器的命令行。-I path当编译器通过配置标志配置时,您可以知道这一点--with-gnu-as。
注意:类似的情况也适用于链接。您可能不想(ld手动)调用链接器,除非您正在制作静态可执行文件或平面二进制文件;如果您要制作在主机系统上运行的普通可执行文件,请使用gcc或代替。g++它将添加许多链接所需的选项,例如多库路径、搜索路径等,您不想手动调整这些选项。
(int $0x10不过,这是一个 16 位 BIOS 调用,它无法在现代主流操作系统下工作,只能在 DOS 或旧版 BIOS 引导加载程序下工作。)