我目前正在尝试在GNU汇编器中构建一个两阶段的引导程序。我使用as
命令来编译程序集文件,并使用ld
命令将它们链接到最终的二进制文件。预先提供一些信息:
$ as --version
GNU assembler (GNU Binutils for Debian) 2.28 [...]
This assembler was configured for a target of `x86_64-linux-gnu'
还有ld
:
$ ld --version
GNU ld (GNU Binutils for Debian) 2.28 [...]
受影响的程序集文件:
.code16
.section .test
label: .short 0x1234
.section .text
.global _setup32
_setup32:
cli
xor %ax, %ax
# Some more code [...]
还有用于构建二进制文件的链接描述文件:在有人问之前,以下链接描述文件是引导加载程序的第二阶段,因此是0x8000
的起源。
OUTPUT_FORMAT(binary)
ENTRY(_setup32)
SECTIONS
{
. = 0x8000;
_SETUP_START = .;
.test ALIGN(0x10) : {
*(.test*)
}
.text ALIGN(0x10) : {
_TEXT_START = .;
*(.text*)
_TEXT_END = .;
}
.rodata ALIGN(0x10) : {
_RODATA_START = .;
*(.rodata*)
_RODATA_END = .;
}
.data ALIGN(0x10) : {
_DATA_START = .;
*(.data*)
_DATA_END = .;
}
.bss ALIGN(0x10) : {
_BSS_START = .;
*(.bss*)
_BSS_END = .;
}
/DISCARD/ : {
*(.comment*)
}
_SETUP_END = .;
}
但是,在构建了最终setup.bin
文件之后,值0x1234
不在hexdump的开头。实际上,它甚至不包含在最终版本中。引导加载程序工作得非常好,我无法将变量或一般的字节分配给各个部分。
我在Makefile中使用以下非常基本的规则:
$(SETUPBIN): $(SETUP).o
$(LD) -T setup.ld $(SETUP).o -o $@
%.o: %.asm
$(AS) $< -o $@
此外:我了解GNU AS指令.text
和.data
,但是它们仅将指令和字节存储在二进制文件的固定位置:.text
指令中的所有内容都位于二进制文件的开头,而.data
中的所有内容都在二进制文件的末尾。
如何将所有内容放在自定义部分?