我已经很久没看过计算机是如何启动的,所以我开始编写自己的加载程序,它将启动到IA-32e模式并使用一些虚拟代码初始化所有CPU来运行。我相当远,但我已经厌倦了在汇编程序中编写琐碎的东西。
这是我想要实现的玩具案例。假设我想编写一段简单的代码来打印C风格的字符串,并在内存中的某个固定位置跟踪光标。 C实现将是以下几行(这段代码是未经测试的,我是在动态编写的,所以不要评论错误,因为它们不相关):
#define VIDEORAM_ADDRESS 0xa0000
#define VIDEORAM_LINE_LENGTH 160
#define VGA_GREY_ON_BLACK 0x07
#define CURSOR_X 0x100 /* dummy address */
#define CURSOR_Y 0x101
void printk(const char *s)
{
volatile char *p;
int x, y;
x = *(volatile char*)CURSOR_X;
y = *(volatile char*)CURSOR_Y;
while(*s != 0) {
if(*s == '\n') {
y++;
y = y >= 25 ? 0 : y;
x = 0;
} else {
x++;
if(x >= 80) {
y++;
y = y >= 25 ? 0 : y;
x = 0;
}
p = (volatile char*)VIDEORAM_ADDRESS + x + y * VIDEORAM_LINE_LENGTH;
*p++ = *s++;
*p = VGA_GREY_ON_BLACK;
}
}
*(volatile char*)CURSOR_X = x;
*(volatile char*)CURSOR_Y = y;
}
我可以使用生成gcc -m32 -O2 -S printk.c
的{{1}}进行编译。我的问题本质上是如何将它与手写的汇编文件结合起来?最终结果当然应该是除了机器代码和数据的单个二进制blob由BIOS加载到printk.s
之外,如果我想将代码包含在从磁盘加载的第1阶段加载器中切换到保护模式后调用它。
是否可以在手写的程序集文件中的某处放置0000:7C00
指令以获取代码?不幸的是,gcc在.s文件中为GNU汇编程序发出了各种指令,我真的只想要.include
函数的代码。
有没有一些规范的方法呢?