作者:四海
VC的编译器CL是专门为WINDOWS系统而设计的,就算是一个只有一个空函数的代码被编译出来就有几十KB,如:
//demo.c
void main()
{
}
上面的代码用CL.EXE生成为exe文件就有几十KB,对于我们写OS的来说,多出的当然是些无用代码.因此,我觉得,CL.exe不适合编译OS的原代码.
我的意思是说,用VC编辑代码,再用Borland C/C++ 5.5 的bcc32.exe 编译代码,再用masm611的link 连接OBJ文件,再用EXE2BIN.EXE 将连接后的EXE文件转换成纯BIN文件.搞定!
示范:
假如,我的系统目前只有二个原代码文件start.asm system.c,其功能简介如下:
start.asm 实现切换到32位保护模式(protected mode),然后跳转到32位代码执行初始化.
system.c 实现初始化(由于这里是个示范系统,别的就不必管了).
第一步,用VC编辑这两个文件.它们的内容如下:
;start.asm
;realize the change from 16-real to 32protected mode
;无心,2005 copyright
.386p
code16 segment use16
start16:
;set temp stack
mov ax,9000h
mov ss,ax;
mov sp,0
;set code segment = data segment
push cs
pop ds;
;Load gdt and idt and set pe bit in CR0
lgdt fword ptr MyGDT
lidt fword ptr MyIDT
mov eax,cr0 ;Get cr0
or eax,1b ;Set PE(protected enable)bit
mov cr0,eax ;Store cr0,so the CPU is in P mode
jmp flush ;clear the order pipe
;FAR JUMP to 32-bit code
flush:
db 66h,0eah ;far jmp to 32-bit segment
dword 30000000h ;假设32位代码开始于30000000h,
;offset (EIP) in new segment
word 0000000000001000b ;Selector in gdt
MyGDT:
WORD 0800h
DWORD 30000h ;假设GDT在30000h
MyIDT:
WORD 0800h
DWORD 40000h ;假设IDT在40000h
code16 ends
end start16
//-------------------------------------------------
//system.c
/*
implement the intializtion of the system and do other thinigs
2005 by ME :)
*/
void init_idt();
void init_timer();
void init_process_system();
void idle_this_process();
void start32()
{
_asm
{
;set stack for 32BIT CODE
mov eax,10000h
mov ss,ax;
mov eax,0ffffffh
mov esp,eax;
}
init_idt();
init_timer();
init_process_system();
//....................
idle_this_process();
}
void idle_this_process()
{
while(1)
{
_asm hlt;
}
}
void init_idt()
{
//........
}
void init_timer()
{
//........
}
void init_process_system()
{
//.........
}
//END
第二步,用 masm611编译start.asm ,用Borland c++ 5.5 编译system.c
ml -c start.asm
bcc32 -c system.c
第三步,用masm611的link.exe 来连接这两个OBJ文件.
link start.obj system.obj
第四步,用exe2bin.exe转换start.exe(连接后就生成该文件,但还不是BIN文件)成纯BIN文件.
exe2bin start.exe myos.bin
搞定!
由于不是用VC的CL.EXE编译,所以,不会产生"垃圾"代码,转换后纯BIN文件和你的原代码一一对应,不信,反编译看看:
首先,用VC打开myos.bin,你会看到:
0000:B8 00 90 8E D0 BC 00 00-0E 1F 2E 0F 01 16 2A 00
0010:2E 0F 01 1E 30 00 0F 20-C0 66 83 C8 01 0F 22 C0
0020:EB 00 66 EA 00 00 00 30-08 00 00 08 00 00 03 00
0030:00 08 00 00 04 00 00 00-55 8B EC B8 00 00 01 00
0040:8E D0 B8 FF FF FF 00 8B-E0 E8 19 00 00 00 E8 19
0050:00 00 00 E8 19 00 00 00-E8 02 00 00 00 5D C3 55
0060:8B EC F4 EB FD 5D C3 55-8B EC 5D C3 55 8B EC 5D
0070:C3 55 8B EC 5D C3
第一个(偏移地址0000)是 B8 00 90,它的意思是:MOV AX,9000,余下的是:
B80090 MOV AX,9000
8ED0 MOV SS,AX
BC0000 MOV SP,0000
0E PUSH CS
1F POP DS
............
是不是和你的start.asm中的代码一一对应啊?
总结
我们用VC编辑代码,也就是说用VC输入代码,而不是用它的CL.EXE编译代码,编辑和编译是分开的.我们用Borland c/c++ 5.5 编译代码,用MASM611的link.exe连接编译后的obj文件,再用exe2bin.EXE转化成纯二精致文件.
转自:http://godmom.blog.sohu.com/