我的嵌入式历程 - zjhfqq的BLOG http://zjhfqq.52rd.net - 复制 - 收藏
zjhfqq 发表于 2007-4-12 16:32:00

作者:四海

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/

阅读全文(1944) | 评论(7)
评 论
7楼 52RD网友(游客) 发表于 2009-10-17 13:05:00
另外开头地址去掉org 100h的话,也可以生成bin文件,但如果写成org 7c00h等等其他的地址的话,就会报错。再说如果想写启动代码,必须定义开头地址吧,所以博主所说的方法不太可行
6楼 52RD网友(游客) 发表于 2009-10-17 12:24:00
exe2bin将exe转换成bin文件是有条件的,博主知道吗?? 首先必须只能有一个段,另外开头偏移地址必须是org 100h,不要误导人好不好呀!!
5楼 zjhfqq 发表于 2009-5-19 11:49:00
呵呵,转载的。我的理解是VC的编译工具是针对MS的操作系统及文件系统的编译,所以默认编译的时候会加上诸如MZ头之类的信息,这样出来的就不是“纯”的二进制文件,不知道对不对。但是应该像4楼的朋友说的,CL应该是有办法生成干净的二进制文件的,比如做OS的BIN。 欢迎大家探讨,最好有一定的分析说明,或者是方法对策。
4楼 52RD网友(游客) 发表于 2008-11-13 9:45:00
CL编译垃圾代码完全是对MS的诽谤 我一直都在用CL做32bit部分binary 很理想
3楼 52RD网友(游客) 发表于 2008-9-2 22:11:00
生成的代码是32位吗? 值得怀疑!
2楼 freakie(游客) 发表于 2008-4-16 21:15:00
我觉得和用不用cl没有关系。bin和asm代码对应是ml的工作吧,用cl还是用bcc只是对system.c生产的代码有影响。并且经过优化的话,cl编译出来也是很小的。个人愚见,仅供参考,呵呵。
1楼 zjhfqq 发表于 2007-4-12 16:40:00
这里讲了如何在WINDOWS环境下开发一个BIN文件的步骤,对于编写BOOTLOADER和OS的同志应该有用。
9 1 :
昵 称: 匿名
验证码: 3258
博 主
进入zjhfqq的首页
博客名称:我的嵌入式历程
日志总数:83
评论数量:161
访问次数:173899
建立时间:2007年3月27日
导 航
日 历
«Mar.2010»
123456
78910111213
14151617181920
21222324252627
28293031
公 告
本博客主要用于记载个人学习笔记与资料收藏,希望对自己和他人都有帮助。其中有些资料都来源于网络,我转载时尽可能地表明文章出处与原作者姓名。
日 志
评 论
链 接