我对x86汇编语言非常感兴趣,想了解底层知识,于是我找到了这个极好的仓库(链接),里面有很多例子可以从EFI shell运行。
当我查看这个hello world例子时,发现有一个链接脚本,内容如下:
ENTRY(mystart)
SECTIONS
{
. = 0x7c00;
.text : {
entry.o(.text)
*(.text)
*(.data)
*(.rodata)
__bss_start = .;
/* COMMON vs BSS: https://dev59.com/qGQn5IYBdhLWcg3wcWvM */
*(.bss)
*(COMMON)
__bss_end = .;
}
/* https://stackoverflow.com/questions/53584666/why-does-gnu-ld-include-a-section-that-does-not-appear-in-the-linker-script */
.sig : AT(ADDR(.text) + 512 - 2)
{
SHORT(0xaa55);
}
/DISCARD/ : {
*(.eh_frame)
}
__stack_bottom = .;
. = . + 0x1000;
__stack_top = .;
}
我无法理解为什么需要它?只是为了指定加载地址吗?我的一般理解是,当存在多个目标文件时,链接器脚本更有用,可以用来定义如何将来自多个目标文件的节合并成单个可执行文件。
如果在这个例子中没有指定链接器脚本会发生什么?(肯定至少有两个目标文件——一个来自.s
,一个来自.c
)