Pan*_*der 1 assembly gcc operating-system kernel bootloader
我正在学习操作系统开发和课程初学者.我想在实模式环境中构建我的系统,这是一个使用C语言的16位环境.
在C中,我使用函数asm()
将代码转换为16位,如下所示:
asm(".code16")
Run Code Online (Sandbox Code Playgroud)
在GCC的语言中生成16位可执行文件(不完全如此).
题:
假设我有两个头文件head1.h
和head2.h
和main.c
文件.main.c
文件内容如下:
asm(".code16");
#include<head1.h>
#include<head2.h>
int main(){
return 0;
}
Run Code Online (Sandbox Code Playgroud)
现在,自从我开始我的代码的命令生成16位可执行文件,然后包括head1.h
和head2.h
,我需要做的,我创建的所有头文件一样吗?(或)添加asm(".code16");
一次是否足够?
操作系统:Ubuntu
编译器:Gnu CC
回答你的问题:asm
块足以出现在翻译单元的开头.
所以在开头就把它放一次就行了.
但是你可以做的更好:你可以完全避免它,使用的-m16
命令行选项(可从5.2.0)代替.
但你可以做得更好:你可以完全避免它.
的效果-m16
和.code16
是使32位代码可执行在实模式下,这是不产生实模式的代码.
看
16.C
int main()
{
return 4;
}
Run Code Online (Sandbox Code Playgroud)
提取原始.text段
>gcc -c -m16 16.c
>objcopy -j .text -O binary 16.o 16.bin
>ndisasm 16.bin
Run Code Online (Sandbox Code Playgroud)
我们得到
00000000 6655 push ebp
00000002 6689E5 mov ebp,esp
00000005 6683E4F0 and esp,byte -0x10
00000009 66E800000000 call dword 0xf
0000000F 66B804000000 mov eax,0x4
00000015 66C9 o32 leave
00000017 66C3 o32 ret
Run Code Online (Sandbox Code Playgroud)
这只是填充了操作数大小前缀的32位代码.
在真正的386前机器上,由于66h操作码是UD,因此无法工作.
有一些旧的16位编译器,如Turbo C 1,可以正确解决实模式应用程序的问题.
或者,尽快切换到保护模式或考虑使用UEFI.
1可在线获取.这个编译器和我一样老!