启动代码

 X86   CPU   原来是用于个人计算机的,大家都知道的如   8086/88,80186/188,80286,80386,80486,Petium,Celeon,Pentium   II……,随着个人计算机的发展,许多原来的CPU纷纷被淘汰,但这些处理器并未退出历史舞台,继续在各个领域发挥着作用,在工业控制领域,80x186/188EA,80x186/188EB,80x186/188EC,80386EX等得到广泛的应用。    
   
          主要型号有:Intel   80186/188,   80186/188EA,   80186/188EB,   80186/188EC,   80386EX   ……,   Intel的站点http://www.intel.com。    
   
          AMD   80186/188,80186/188ED,80186/188EM,80186/188ES,ELAN300,ELAN400,最近还推出了用于网络的80186/188CH,型号我记不清了,有兴趣的可以到http://www.amd.com去找。    
   
          比较而言我自己觉得AMD的产品要好一些,设计简单,提供的外部资源(指定时器、中断控制器、I/O口、地址译码、DMA控制器、DRAM控制器……)要多一些,另外ELAN300,ELAN400简直就是一台个人计算机,它集成了PC机除了DRAM和磁盘控制器之外几乎所有的电路(把LCD显示器接口也集成到里面了,包括RTM,TMR,INT   Controller,DMA,DRAM   Controller,SIO,KEYBOARD……)。若用DISKONCHIP作为硬盘的话加上DRAM,LCD显示器,键盘,网卡就是一台PC机了。    
   
          为了适应工业领域的应用,简化用户的开发难度,Intel和AMD两大公司推出了自己各有特色的产品,特别值得一提的是AMD公司的产品,应用起来特别是硬件设计非常简单,但AMD公司没有推出象   Intel     AppBuilder一样的工具,编程还是要困难一点。另外X86系列的一个缺点就是仿真器非常昂贵,我们可以在PC机上作软件调试,编译器用   MSC,TC,BC   均可。但生成的是   .EXE   文件需要操作系统加载运行,无法写入ROM里,我们需要一个定位工具,把   .EXE   文件的重定位段定位.另外由于没有了操作系统的支持,所以需要重写   C   语言的启动文件,在TC下有一个   C0X.OBJ的文件(X=T,S,M,L,H为Tiny,   Small,   Medium,   Large,Huge模式,对应的有一个C0.ASM的汇编源程序),完成   C   语言的初始化,设置堆栈,与操作系统接口……,我们重写   C   语言的启动文件就是重写C0.ASM.   当然若能买一个嵌入实时操作系统就不要这样麻烦了,可悲的是嵌入实时操作系统太贵,也有免费的,或者学习起来太难,因为没有资料,用户又太少。    
   
   
  --------------------------------------------------------------------------------    
   
          本人在用80C188EB开发过一个通讯控制器,配有8个串口,其中有两个为同步/异步,6个异步。配有512K   ROM,512K   RAM,RTM,8K串行EEPROM。用TC作开发工具,除了应用程序外,主要的难点在于:C语言的启动代码;定位工具;串行EEPROM的接口库。这里仅介绍C语言的启动代码。    
   
          本来,各种C语言编译器都提供启动代码,以X86为例,无论是TC、MSC、BC都有。TC在不同模式下启动代码不一样,为C0X.OBJ.一般编程,用不着去修改启动代码。但有的场合就有必要了。笔者为一套系统开发软件时发现:一套系统当没有操作系统时,要想使得系统正常运行是相当困难的。笔者开发的系统CPU为80C188EB,无操作系统,开发工具为TC2.0。为了能使得系统运行,又不能用太低级的语言如汇编,可谓历尽辛苦(当然可以买现成的开发工具和仿真工具,太贵)。    
          笔者重写了TC的启动代码,另外还改写了一个重定位工具(把EXE文件变为可直接写入ROM去的文件)。因为很少见到类似文章。下面把主要内容写出来,以飨读者。以后我准备把这个工具完善以下,做成一个重新定位的工具。      
   
          C语言的启动代码如下:    
  ;   tcstart.asm    
  ;   for   d000   code   only,   external   eprom   on   memory   card    
  ;   FOR   PC   ROM      
  extrn     _main:far;      
   
  /*     说明外部的C语言的MAIN()   函数,这也是   C   语言为什么非要从MAIN()开始的原因   */    
  _text   segment   byte   public   "CODE"   ;   /*   C语言生成的代码段   */    
  _text   ends    
  _textend   segment   para   public   "CODEEND";     /*   代码段的结束段   */    
  _textend   ends    
  _data   segment   para   public   "DATA";   /*   C语言生成的初始化数据段   */    
  _data   ends    
  _dataend   segment   para   public   "DATAEND";   /*   初始化数据段的结束段   */    
  _dataend   ends    
  _bss   segment   para   public   "BSS"     ;/*   C语言生成的非初始化数据段   */    
  _bss   ends    
  _bssend     segment   byte   public   "BSSEND";/*   C语言生成的非初始化数据结束段   */    
  _bssend     ends    
  _stack   segment   para   stack     "STACK"   ;   /*   堆栈段   */    
  _stack   ends    
  DGROUP   group   _DATA,   _DATAEND,   _BSS,   _BSSEND   /*   把数据的段构成一个组,代码连在一起   */    
  CGROUP   group   _TEXT,   _TEXTEND   /*   把代码的段构成一个组,代码连在一起   */    
  _TEXT   segment         ;   /*   代码段   */    
  assume   CS:CGROUP,   DS:DGROUP,   ES:DGROUP,   SS:_STACK    
   
  start:   cli                         ;   disable   interrupts    
  mov   ax,   _STACK   ;   initialise   stack    
  mov   ss,   ax    
  mov   ax,   offset   stackend    
  mov   sp,   ax    
  mov   ax,   seg   _BSS   ;   /*   BSS   SEG   CLEAR   */    
  mov   es,   ax    
  mov   cx,   offset   DGROUP:endbss    
  mov   di,   0          
  mov   ax,   0    
  rep   stosb   ;   write   to   ES:DI    
  mov   ax,   seg   DGROUP     ;初始化数据段    
  mov   es,   ax   ;   point   ES   to   _DATA    
  mov   cx,   offset   DGROUP:enddata    
  mov   si,   0    
  mov   di,   0    
  assume   ds:CGROUP    
  mov   ax,   seg   _TEXTEND:codeend    
  inc   ax    
  mov   ds,   ax   ;   point   DS   to   _CONST    
  rep   movsb   ;   copy   _CONST   to   _DATA    
  push   es   ;   point   DS   to   _DATA    
  pop   ds    
                                                            ;下面内容非PC   机可以不要    
  mov   al,   80h             ;   enable   NMI    
  out   0a0h,   al    
  mov   al,   0bch           ;   enable   8259   PIC     1011-1100   (irq0,1,6   enabled)    
  out   21h,   al    
                                                            ;上面内容非PC   机可以不要    
  sti   ;   enable   interrupts    
  call   _main       ;   CALL   C   MAIN()      
  jmp   start       ;    
  _TEXT   ends    
  _TEXTEND   segment    
  public   codeend    
  db   16   dup(?)   ;   a   paragraph,   thus   _CONST   is   one   byte   more    
  codeend   label   byte    
  _TEXTEND   ends    
  _STACK   segment    
  db   1024   dup   ("STACK");/*   预留的堆栈空间   */    
  stackend   label   word    
  _STACK   ends    
  _BSSEND   segment    
  public   endbss    
  endbss   label   byte    
  _BSSEND   ends    
  _DATAEND   segment    
  public   enddata    
  enddata   label   byte    
  _DATAEND   ends    
                  end    
  编译连接:    
  tasm   /mx   tcstart    
  bcc   -a-   -c   -f-   -G-   -K   -B   -ml   -M   -N-   -O-   -r-   -v-   -y-   -Z-   -S   -O-     1.c    
  tlink   /m   tcstart     1   tclib,     1,     1    
  locate     1;   LOCATE   工具,本人无源代码。    
          本人重写了一个工具,   EXEBN1.EXE   连同本文一起贡献给读者。    
          EXEBN1中在文件长度>64K时或使用CONSTANT说明时,会出问题,正式版本600元。    
          另外,为自行设计的系统写BIOS,也可代为设计嵌入式控制系统。(16BIT   OR   32BIT,186   OR   386   )    

你可能感兴趣的:(c,语言,工具,开发工具,byte,编译器)