我制作了一个非常简单的一级引导加载程序,它执行两个主要操作:从 16 位实模式切换到 64 位长模式,并从硬盘读取接下来的几个用于启动基本内核的扇区。
对于基本内核,我尝试用 C 而不是汇编编写代码,对此我有一些疑问:
- 如何编译并链接 nasm 文件和 C 文件?
- 编译文件时,应该编译为16位还是64位?因为我要从 16 位切换到 64 位。
- 如何将更多文件从 C 语言或汇编语言添加到项目中?
我重写了问题以使我的目标更清晰,因此如果需要源代码请告诉我添加它。
最佳答案
since I am also linking a nasm file with the C file, it spits an error from the nasm object file, which is relocation R_X86_64_16 against .text' can not be used when making a shared object; recompile with -fPIC
您的问题之一可能是在 nasm
汇编程序文件中(您在问题的初始版本中没有显示该文件)。它应该只包含 position-independent code (PIC)因此无法生成 object file与 relocation R_X86_64_16
(在您编辑的问题中, mov sp, main
显然不是 PIC,您应该使用 x86-64 的指令指针相对数据访问,并且您不能定义 main
都在 nasm
文件和 C 文件中,并且链接时不能混合 16 位模式和 64 位模式。
学习ELF ,然后 x86-64 ABI了解 PIC 文件中允许何种类型的重定位(以及汇编程序文件应遵循哪些约束来生成 PIC 目标文件)。
使用objdump(1) & readelf(1)检查对象文件(以及共享对象和可执行文件)。
一旦您的 nasm
代码生成 PIC 目标文件,请与 gcc
和 use 链接gcc -v
了解幕后发生的情况(您将看到额外的库和目标文件,包括 crt0、-lgcc
和 -lc
,被使用)。
也许您需要更好地了解编译和链接。阅读 Levine 的书 Linkers and Loaders , Drepper 的论文 How To Write Shared Libraries ,以及-关于编译-Dragon book .
您可能想要与 gcc
链接,但使用您自己的 linker script 。另请参阅this回答一个非常相关的问题(可能与您的动机相似);那里的引用资料与您高度相关。
关于gcc - 将 NASM 和 64 位 C 代码编译并链接到引导加载程序中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51939790/