djgpp 中断写法

献给初学者的DJGPP教程

(2010-07-13 15:02:40)
标签:

it

分类:DOS编程

献给初学者的DJGPP教程

自从用上LINUX后就用够了WINDOWS,但是好多开发还脱离不开DOS,真是没办法!早就听说FREEDOS和MSDOS完全兼容,而且遵循的是GPL协议,所以下定决心脱离WINDOWS,装了个FREEDOS!开发工具当然不能再用TURBO C啊等等原先商业化的东西了,用就用个纯GNU的平台!好,就把TURBOC换成DJGPP吧,还有MASM和TASM,全部给我扔掉,换成NASM!编辑器呢?用着EDIT根本就不爽,换成了DOS版的VIM,也是GNU工具!不好意思,中文平台还是得用UCDOS,因为似乎还没有GPL协议的中文化DOS平台呢,还好UCDOS是免费的了,不会让我的系统中存在D版软件了,我也没有做贼的感觉了!^-^

    OK,这一切都搞定了,可是面对DJGPP和NASM突然发觉自己什么都不会了,以前用 TURBOC和MASM写代码的时候调用中断啊,交互编程啊,现在都不知道怎么做了,靠,和当初刚刚接触LINUX怎么一样啊!只好到http://delorie.com/djgpp去看了,全他妈的E文的,硬着头皮看吧!总算找到了一些用户指南,读懂了,基本上可以解决以上问题了!想一想,那么多和自己一样的家伙们肯定也是一样的头疼,所以写出来和大家一起分享,并非是翻译的,因为我没有耐心去翻译那些洋话连篇的东西,还是根据我的理解来写一份教程吧,不过大牛们就不必看了!另外,本教程假设您对turboc或者DOS下的其他C/C++有一定了解并且作过一些中断调用,中断驻留,显存映射操作以及C/C++和ASM混合编程!
     OK,废话少说,本教程分为如下四个部分:
      1如何调用中断;
      2 如何往VIDEORAM中写入数据;
      3 如何写中断驻留程序;
      4 如何调用NASM写的汇编函数;
      5相关协议以及免责声明及其他
 _____________________________________________________________________________________
      1如何调用中断:在DJGPP中调用实模式中断和在TURBOC中使用INT86调用中断在形式上是很类似的,看下面的例子(来自http://delorie.com/djgpp): #includevoid main(void){ __dpmi_regs r; r.x.ax = 0x13; r.d.ebx = 0x10000;r.h.cl = 4; r.h.dh = 5; __dpmi_int(0x10, &r); }__dpmi_regs是一个结构,其中包含所有的80386用到的寄存器,如果你要使用8位寄存器可以这样__dpmi_regs.h.xx可以是ah, al, bh,bl等寄存器),如果你要使用16位寄存器可以这样__dpmi_regs.x.即用x替换掉h即可),如果要使用32位寄存器,把h用d替换就可以了!上面的代码就是调用int10中断,把显示模式设置为0x13(320*200256)。当中断执行完毕时,传给__dpmi_int的__dpmi_regs类型参数中将包含寄存器的新值,你可以通过检测这些新值来分析中断的执行情况!注意,这些中断调用都是实模式下的!_____________________________________________________________________________________
      2 如何往VIDEORAM中写入数据: 往VIDEO RAM中写入数据有两种方法,这两种方法个有优缺点,您需要根据情况选择使用! 第一种方法:下面是代码:#include void main(void){ char *screen; __dpmi_regs r; r.x.ax =0x13; r.d.ebx = 0x10000; r.h.cl = 4; r.h.dh = 5; __dpmi_int(0x10,&r); if (__djgpp_nearptr_enable() == 0) return 0;screen = 0xa0000 + __djgpp_conventional_base; screen[0] = 4;__djgpp_nearptr_disable(); } 这个例子在屏幕的左上角画一个红色的点。这种方法有下面两种缺点:<1>在调用一些特定的DPMI过程后,你必须重新计算videoram的近指针值! <2>在windowsNT下不能用(至少在XP下是不能用的,但是在纯DOS下没问题)! 因此,一般并不推荐使用这种方法! 下面是第二种方法:#include #include int main(){ int x=0,y=0; char * screen;__dpmi_regs r; r.x.ax = 0x13; __dpmi_int(0x10, &r);_farsetsel(_dos_ds); _farnspokeb(0xA0000, 4); return 1; }这个例子在屏幕的左上角画一个红色的点。它也有一个缺点,那就是比第一种方法要稍微慢一点。但是它比较安全,据说能够在NT下使用(但是我在XP上验证的效果很糟糕),而且不必重新计算VIDEORAM的指针,在Allegro库中就是使用的这种方法,所以它的速度也是比较不错的,所以推荐使用这种方法!_____________________________________________________________________________________
      3如何写中断驻留程序:这儿有个程序,汉化自DJGPP的用户指南,不多说了,看程序,里面的注释已经很清楚了!
 #include
#include
#include
#include
#define LOCK_VARIABLE(x) _go32_dpmi_lock_data((void*)&x,(long)sizeof(x)); #define LOCK_FUNCTION(x)_go32_dpmi_lock_code(x,(long)sizeof(x));
#define TIMER 8
int counter = 0;
void TickHandler(void){ counter++; }
 int main(void)
{
_go32_dpmi_seginfo OldISR, NewISR;printf("将要把新的中断处理程序连结到旧的中断处理程序上..n"); getkey();LOCK_FUNCTION(TickHandler); LOCK_VARIABLE(counter);_go32_dpmi_get_protected_mode_interrupt_vector(TIMER,&OldISR); NewISR.pm_offset = (int)TickHandler;NewISR.pm_selector = _go32_my_cs();_go32_dpmi_chain_protected_mode_interrupt_vector(TIMER,&NewISR);while (!kbhit()) printf("%dn",counter);printf("正在恢复原有的时钟中断。。。。。。n");_go32_dpmi_set_protected_mode_interrupt_vector(TIMER,&OldISR); return 0; }_____________________________________________________________________________________
      4如何调用NASM写的汇编函数:下面这个例子是我自己写的,共有三个文件:将下面的代码存为asm.asm:
[BITS 32] [GLOBAL _AddFour__FUi] [SECTION .text] ;---------------------------------------------------------------------------; 原型声明: unsigned int     
      AddFour(unsigned int x); ;Returns: x + 4 ;---------------------------------------------------------------------------
      x_AddFour equ 8_AddFour__FUi:
      push ebp mov ebp, esp
      mov eax, [ebp +x_AddFour]
      add eax, 4
       mov esp,ebp
      pop ebp
      ret
      将下面的代码存为c.c:
      #include extern unsigned intAddFour(unsigned int);
      int main(void)
      {
           printf("AddFour(4) = %in", AddFour(4));
           return 0;
      }
       将下面的代码存为maker.bat:
       @echo off nasm -f coff asm.asmgcc -o c.exe c.c asm.o c.exe
      最后输入maker,如果成功将输出:AddFour(4)=8 不成功的原因可能是你的NASM也许版本太老,也或者不是32位的NASM(非32位NASM不认识coff目标文件格式),也或者是其他不可想象的原因。
 _____________________________________________________________________________________
      5 相关协议以及免责声明及其他
      本文挡是本人参考http://delorie.com/djgpp上的某些文挡写成的,相当一部分直接来自于那些文挡,所以本人只保留汉化的版权,但是您可以任意转载而且可以任意修改!
 由于本人真正使用DJGPP的时间并不长,也没有时间仔细研究,所以并不能保证本文相关内容绝对正确,如果给您带来某些灾难性后果,本人概不负责!如果您有问题,请通过邮
件和我联系,
      我的邮箱是:xy_god@163.com也可以到我的主页留言,我的主页是:http://www.xygod.mycool.net
来源:http://www.cn-doc.com/_system_linux_doc/2005_09_19_21/20050919210013433.htm

--------------------------------------------------------------------------------------

DJGPP 
       是一个免费的GNUC/C++编译器,适用于MSDOS,386保护模式。完全适用于专业水平的程序设计。DJGPP和Linux一样,是不可多见的最优秀的Freeware。Id的新游戏Quake就是用了DJGPP编译。相比PC上其它的编译器,djgpp有如下优点: 
1)  极好的可移植性。Gcc/gpp是著名的跨平台编译器,在各种unix,win32,msdos下都有版本。
2)   丰富的工具箱  
3)   可访问4G地址,支持虚存,而DOS4GW有64M的限制。 
4)  强大的DOS集成环境(rhide),功能超过了Borland C++  3.1IDE。 
5)完全免费。  
       DJGPP目前的版本是2.02,gcc2.7.2.1,整套的djgpp包括:gcc, gpp(c++), Objective C,gnu的文件/文本处理工具,gnu  pascal, gnu asm, rhide, DPMI扩展器cwsdpmi。相关的工具有:pmode for DJ, SWORD窗口系统,X11窗口系统,RSXNT Win32扩展,allegro游戏库,grx2.0图形库,Borland  BGI兼容图形库,jptui  norton风格的DOS文本界面,DOS下多线程扩展(抢先式), pgcc 针对pentium优化的编译器,nasm 一个MASM语法风格的coff汇编器;PLUSH 3D engine,VPE post-doom engine, sb05, midas sound library, 等。  

推荐:DJGPP.rar( http://ishare.iask.sina.com.cn/f/9513099.html?w=?w=MTIyNzAxMDAyNQ==)

------------------------------------------------------------------------------------------

题记:我是一个从学校出来刚刚工作了几天的新人,这些是我工作这几天里的一些体会和想法,希望能对在校的学生或者是跟我一样刚出来工作的人们有一些帮助。

=================================================================================

忙了几天,今天终于有点时间来写写这几天的一些心得体会了。

我们公司是做数控系统的,所以我的工作是在DOS下做一些底层的开发。刚刚来到这公司,Team Leader叫我先熟悉一下DJGPP这个开发工具,这是一个DOS下的GCC工具(以前学LINUX课程的时候有学过GCC,但那时对这个不感兴趣,没怎么用心学,早就忘光了),有一个集成开发环境(rhide),听说跟BC差不多(不好意思,我只用过TC,没用过BC)。跟TC、BC那些最不一样的地方是,它提供了一个DOS下的32位保护模式(DPMI)。

刚刚接触GJGPP,最大的难题是市面上根本没有这方面的书,所有的资料都只能来源于网上,而且绝大部分都是英文的资料。熟悉了一下开发环境后,带我的那个老员工让我先写一个DOS下的中断程序给他看看。我以前没有写中断程序的经验,写这个程序可花了我不少的时间。

“中断”这个概念,如果从理解的角度来看,书上的定义是很好理解的,但从开发者的角度来看就很不一样了。看了N多资料后,终于才对“中断”有了些理解了。原来所谓的DOS下的“中断”其实就是我们在Windows 中所说的“事件”和消息。当我们的某个操作或者是程序的某一条指令产生了一个中断后,CPU就会停下当前的工作来处理这个中断。就像在Windows中发生了一个事件而产生了一条消息,系统就会来处理这条消息一样(当然,这都涉及到优先级的问题,具体还要看操作系统)。

在DOS下的中断有软件中断和硬件中断之分。软件中断是由我们的程序或者是操作系统发出的,而硬件的中断则是由硬件的状态改变产生的。我们的程序可以使用“系统调用中断”来调用系统的各项功能(这就像我们在Windows 中使用 API 函数一样),我们也可以通过改写中断处理函数来实现我们想要的操作(这就像我们在 Windows里写消息处理函数一样)。

下面我列了一下我这几天所写过的一些程序,在校的学生或都其它有兴趣的人都可以试写一写,如是你以后是做底层开发的话,相信这些对你是很有帮助的!

1、写一个DOS的中断程序。(理解一下中断的概念)

2、改写INT 1CH(时钟中断)的中断处理函数。(学会改写中断处理函数)

3、修改时钟中断发生的时间(默认是55ms)。(学会操作底层硬件)

4、在保模式中直接访问内存。(学习保护模式下的内存操作方式)

这些程序需要你对硬件或者是数据在内存中的存放方式有一定的了解才可以实现,在网上可以找到很多这方面的资料,希望有志在这方面学习和发展的朋友不要被学习中所遇到的困难吓倒,希望中国的IT业会有更好的发展!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值