7

我想在 Windows 中编译这个源代码(它只是一个例子):

start:
NOP
NOP

当我用 NASM 或 FASM 编译它时,输出文件长度为 2 个字节。但是当我用 GNU 汇编器(as)编译它时,输出文件的长度是 292 字节!

如何使用 GNU 汇编器 (as) 将汇编文件编译为原始二进制文件(如 DOS .com)格式?


为什么我这样做?

我想编写自己的简单操作系统,我用 C 编写代码(不使用任何 C 标准库,甚至 stdio.h 或 math.h)并将其转换为程序集:

gcc -S my_os.c -o my_os.asm -masm=intel

然后,我将汇编文件编译为原始二进制文件:

as my_os.asm

然后我将a.out(汇编程序的输出)重命名为my_os.flp并最终使用 VMWare 启动我的操作系统 :)

4

3 回答 3

7

ld --oformat binary

对于快速而肮脏的测试,您可以执行以下操作:

as -o a.o a.S
ld --oformat binary -o a.out a.o
hd a.out

给出:

00000000  90 90                                             |..|
00000002

不幸的是,这给出了一个警告:

ld: warning: cannot find entry symbol _start; defaulting to 0000000000400000

这没有多大意义binary。它可以通过以下方式静音:

.section .text
.globl start
start:
nop
nop

和:

ld -e start --oformat binary -o a.out a.o

或简单地说:

ld -e 0 --oformat binary -o a.out a.o

ld表明入口点不是_start地址,而是地址0

遗憾的是,既不能as也不ld能从标准输入/标准输出获取输入/输出,所以没有管道。

正确的引导扇区

如果您要处理更严重的事情,最好的方法是生成一个干净的最小链接描述文件。linker.ld

SECTIONS
{
    . = 0x7c00;
    .text :
    {
        *(.*)
        . = 0x1FE;
        SHORT(0xAA55)
    }
}

在这里,我们还将魔术字节与链接描述文件一起放置。

链接描述文件最重要的是控制重定位后的输出地址。了解更多关于搬迁的信息:https ://stackoverflow.com/a/30507725/895245

将其用作:

as -o a.o a.S
ld --oformat binary -o a.img -T linker.ld a.o

然后你可以启动为:

qemu-system-i386 -hda a.img

此存储库上的工作示例:https ://github.com/cirosantilli/x86-bare-metal-examples/blob/d217b180be4220a0b4a453f31275d38e697a99e0/Makefile

在 Binutils 2.24、Ubuntu 14.04 上测试。

于 2015-08-26T21:32:26.850 回答
0

使用带有-f bin选项的 NASM 将您的汇编代码编译为原始二进制文件。

于 2011-12-12T23:36:26.383 回答
0
org 100h
nop
nop

可以使用fasm编译:

fasm yourcode.asm targetfilename.com
于 2018-06-22T17:57:58.957 回答