gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 21:59:06 25 4
gpt4 key购买 nike

我想在 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 启动我的操作系统:)

最佳答案

ld --oformat 二进制

对于快速而肮脏的测试,您可以这样做:

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

这对于二进制没有多大意义。可以通过以下方式使其静音:

.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处的代码。

遗憾的是,asld 都无法从 stdin/stdout 获取输入/输出,因此没有管道。

正确的引导扇区

如果您要做更严肃的事情,最好的方法是生成一个干净的最小链接器脚本。 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 上测试。

关于assembly - 如何使用 GNU 汇编器 (as) 将汇编文件编译为原始二进制(如 DOS .com)格式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8482059/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com