嗨,我已经拆解了一些程序(linux),我写的是为了更好地理解它是如何工作的,我注意到主要功能始终以:
lea ecx,[esp+0x4] ; I assume this is for getting the adress of the first argument of the main...why ?
and esp,0xfffffff0 ; ??? is the compiler trying to align the stack pointer on 16 bytes ???
push DWORD PTR [ecx-0x4] ; I understand the assembler is pushing the return adress....why ?
push ebp
mov ebp,esp
push ecx ;why is ecx pushed too ??
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:为什么所有这些工作都完成了?我只了解使用:
push ebp
mov ebp,esp
Run Code Online (Sandbox Code Playgroud)
其余对我来说似乎毫无用处......
我是学习OS开发的新手.从我读过的书中,它说启动加载器会将第一个MBR复制到0x7c00,然后从实模式开始.
并且,示例从16位汇编代码开始.但是,当我查看今天的linux内核时,arch/x86/boot有'header.S'和'boot.h',但实际代码是在main.c中实现的.
这似乎对"不编写汇编"很有用.但是,这是如何在Linux中专门完成的?我可以粗略地想象可能有特殊gcc
选项和链接策略,但我看不到细节.
我一直在用C编写内核.我一直在使用GCC交叉编译器,在Windows系统上编写并以16位实模式为目标.我没有可用于编写内核的C库.我已经开始使用一些代码来假设将字符直接打印到屏幕上.这是一个函数来自kernel.c
:
int main()
{
char *src = (char *)0xB8000000L;
*src = 'M';
src += 2;
*src = 'D';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我使用GCC编译了我的代码,并使用参数-m16
生成将在实模式下运行的代码.我使用这些命令来生成我的kernel.bin
:
gcc -ffreestanding -c -m16 kernel.c -o kernel.o
ld -Ttext 0x10000 -o kernel.pe kernel.o
objcopy -O binary kernel.pe kernel.bin
Run Code Online (Sandbox Code Playgroud)
Stack Overflow用户Michael Petch解决了我的链接器问题,但评论代码本身是不正确的.他发表了这样的评论:
除链接器问题外,您是否尝试将旧的TurboC/MSVC 16位代码转换为GCC?我发现(char*)0xB8000000L可疑.如果它是一个真正的16位C编译器,它可能是好的,如果它是(char far*)0xB8000000L.GCC不是一个真正的16位C编译器,并没有旧式远指针的概念.所以,即使你得到这个代码进行编译,这可能不会做你认为它做的,我假设从-m16选项与GCC你正在尝试创建一个实模式16位内核(而不是保护模式一个) )?
我一直在尝试printf
在C中为我自己的操作系统实现自己的类似功能.我上面提供的代码只是我理解的一小部分.我在程序集中创建了一个bootloader(8086).
迈克尔是对的吗?如果是这样,我该如何解决这个问题并直接写入视频内存0xb8000
?