Board logo

标题: DOS下C的一个代码,求解,谢谢. [打印本页]

作者: pptppt     时间: 2008-4-23 15:24    标题: DOS下C的一个代码,求解,谢谢.

以下是一个C写的DOS运行的代码,是一个程序的部分.是BIOS看门狗的,
请教一下具体每句的意思,如果用Debug 汇编怎么写. 谢谢了.
------------------------------------------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <dos.h>
#include <stdlib.h>
#include <inlines/pc.h>
#include <dpmi.h>
#define INDEX_PORT 0x2e
#define DATA_PORT 0x2f
#define WDTBaseAddress 0xDF300000;
int selector[0];
__dpmi_meminfo mi[0];


void InitWDTimer()
{
        mi[0].address=WDTBaseAddress;                                        //WDT timer base address//
        mi[0].size=0x10;                                                                        //WDT register //
        __dpmi_physical_address_mapping(&(mi[0]));
        selector[0]=__dpmi_allocate_ldt_descriptors(1);
        __dpmi_set_segment_base_address(selector[0],mi[0].address);
        __dpmi_set_segment_limit(selector[0],mi[0].size-1);
}       

void SetWDtimer(unsigned long timer)
{
                _farsetsel(selector[0]);
//; perform unlock sequence for preload 1//
                        _farnspokeb(0x0C,0x80);
                        _farnspokeb(0x0C,0x86);
                        timer = timer * 1000;                                                                // Msec hange to Sec//
                        _farnspokel( 0x00, timer);
//; perform unlock sequence for preload 2//            
                        _farnspokeb(0x0C,0x80);
                        _farnspokeb(0x0C,0x86);
                        _farnspokel(0x04, 0x01);
                        outportl(0x0cf8,0x8000EC00+0x68);                //;enable WDT timer//
                        outportl(0x0cfc,0x00000002);
}
作者: zyl910     时间: 2008-4-24 11:27
InitWDTimer函数还算简单,利用DPMI得到一个指向WDTBaseAddress的选择子。由于该地址超过实模式24位地址范围,所以用到了DPMI(DOS保护模式接口)

至于SetWDtimer函数。
第一句用_farsetsel设好段描述符后,后面的_farnspokeb、_farnspokel就是端口操作,与具体的接口命令字设计有关。
最后的outportl是用来写PCI配置。0x0cf8是PCI地址端口,0x8000EC00是设备号(分为 总线、设备、功能三级,具体位含义去查PCI规范,我不太记得了),0x68是指该设备的0x68地址的寄存器(自定义寄存器,功能不详,与具体的接口命令字设计有关)。0x0cfc是PCI数据端口,该程序往刚才指定的0x68寄存器写了一个32位数据(0x00000002)。

[ Last edited by zyl910 on 2008-4-24 at 11:38 AM ]
作者: zyl910     时间: 2008-4-24 11:34
该程序用到了DPMI,用汇编不好写
再加上有很多32位操作(_farnspokel、outportl),但Debug只支持16位汇编,而且应该没人愿意直接写机器码。用Debug是很不现实的
作者: pptppt     时间: 2008-4-27 18:15
谢谢 2zyl910  我先.试试看. 

[ Last edited by pptppt on 2008-4-27 at 06:30 PM ]
作者: netwinxp     时间: 2008-5-1 16:01
_farpeekb、farpeekw、_farpeekl
_farnspeekb、_farnspeekw、_farnspeekl
_farpokeb、_farpokew、_farpokel
_farnspokeb、void _farnspokew、_farnspokel
这些是dpmi读、写保护模式内存的接口函数。
_farsetsel、 _fargetsel是设置和取得LDT的接口函数。
===以上部分需要学习保护模式编程的资料才能较好滴体会===
后面两句比较简单——
1、该硬件使用PCI配置空间8000EC00段(每段256字节),BUSID=0,DEVICEID=29。
2、其68H是BIOS看门狗定时器使能寄存器(该配置空间具体寄存器分布、格式和功能你最好找厂家索取)。
3、设置该寄存器值为2时使能定时器。
注:定时器的值好像在保护模式内存空间DF300000处
如果你非要用DEBUG来编写,那很多语句只能采用机器语言。推荐你采用masm611,用.386模式,如果你熟悉了保护模式编程,你可以用INT 15H调用完全脱离DPMI。

[ Last edited by netwinxp on 2008-5-1 at 04:39 PM ]
作者: pptppt     时间: 2008-5-10 17:59
谢谢各位,还在学习中!!