标题: 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
谢谢各位,还在学习中!!