int 0x13 的扩展读(ah = 0x42)

原文链接:http://www.mouseos.com/win7/int_0x13.html#42

1、 int 0x13 的扩展读(ah = 0x42)

int 0x13 的 0x42 号功能从磁盘读 n 个 sectors 到 buffer 中。

入口参数:ah = 0x42, dl = 磁盘号(0x80 为硬盘), ds:si = buffer

读入的 buffer 结构,用 c 描述为:

struct buffer_packet
{
    short buffer_packet_size;         /* struct's size(可以为 0x10 或 0x18)*/
    short sectors;                    /* 读多少个 sectors */
    char *buffer;                     /* buffer address */
    long long start_sectors;          /* 从哪个 sector 开始读 */
    long long *l_buffer;              /* 64 位的 buffer address */
} buffer;

这个 buffer_packet 结构大小可以为 16 bytes 或者 24 bytes

当 buffer_packet_size 设置为 0x10,最后的 l_buffer 无效。 buffer_packet_size 设为 0x18 时,l_buffer 需要提供。

注意:

   buffer_packet 结构里的 buffer 地址,它是个逻辑地址,即:segment:offset

  低 word 放着 offset 值,高 word 放着 segment 值。

  切记!

 

 下面是摘自 windows 7 的 MBR 中的典型用法

典型的 int 0x13 第 0x42 号功能用法:

/* 以下是使用 int 0x13 扩展功能读 disk */

00000061  666800000000      push dword 0x0
00000067  66FF7608          push dword [bp+0x8]   /* start sectors for read */
0000006B  680000            push word 0x0
0000006E  68007C            push word 0x7c00   /* buffer address */
00000071  680100            push word 0x1
00000074  681000            push word 0x10   /* 使用 16 bytes 的结构,即不需要 64 位 buffer address */

00000077  B442              mov ah,0x42
00000079  8A5600            mov dl,[bp+0x0]      /* hard disk = 0x80 */
0000007C  8BF4              mov si,sp            /* buffer_packet 的 address(ds:si) */
0000007E  CD13              int 0x13            

 

 

2、 int 0x13 获取磁盘参数(ah = 0x48)

获取的磁盘参数保存在提供的 buffer 里,这些参数包括:

★ 磁盘的 cylinders 数量
★ 磁盘的 heads 数量
★ 每道的 sectors 数
★ 磁盘总共有多少扇区
★ 每个扇区有多少字节

这个 buffer 结构,用 c 描述如下:

struct driver_parameters 
{
    short buf_size;              /* 缓冲区结构的大小 */
    short flags;                 /* 标志 */
    int cylinders;               /* cylinders 数量 */
    int heads;                   /* heads 数量 */
    int sectors_per_track;       /* 每道的 sectors 数 */
    long long sectors;           /* 磁盘总共的 sectors 数 */
    short bytes_per_sector;      /* 每个扇区的 bytes 数 */

} buffer;

下面是摘自 windows 7 的 DBR 中的典型用法:

典型的 int 0x13 第 0x48 号功能用法:

0000008D  1E                push ds
0000008E  83EC18            sub sp,byte +0x18      /* 预留 0x18 个空间 */
00000091  681A00            push word 0x1a         /* 写 buffer 的第 1 个 word ,即:buf_size = 0x1a */
00000094  B448              mov ah,0x48
00000096  8A160E00          mov dl,[0xe]           /* 驱动器 ID,即:0x80 */
0000009A  8BF4              mov si,sp
0000009C  16                push ss
0000009D  1F                pop ds
0000009E  CD13              int 0x13               /* 获取 driver 参数 */


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
#include //器件库 #include //延时函数库 #include //标准I/O函数库 #include //标准函数库 unsigned char m0,m1,m2; unsigned char s,s1; // 单片机定时器0溢出中断服务程序段 // 产生伺服电机动作所需要的脉宽 interrupt [TIM0_OVF] void timer0_ovf_isr(void) { TCNT0=0xBA; if(s<m0)PORTA.0=1;else PORTA.0=0; if(s<m1)PORTA.1=1;else PORTA.1=0; if(s127) { s=0; s1=0; TCCR0=0x00; TCCR1B=0x02; TCNT1H=0xff; TCNT1L=0x59; } } // 单片机定时器1溢出中断服务程序段 // 产生0.5ms的开始脉宽和5ms以上的间隔脉宽 interrupt [TIM1_OVF] void timer1_ovf_isr(void) { #asm("wdr"); //喂狗 TCNT1H=0xff; TCNT1L=0x59; s1++; if(s170) { TCCR1B=0x00;TCCR0=0x01;s1=0;TCNT0=0xBA;} } } void main(void) { unsigned char i,j,count=0; unsigned char c[3]; unsigned int k; // 设置A口为输出状态,并且初始值为低电平 PORTA=0x00; DDRA=0xFF; // 设置B、C、D、E口为高阻输入状态,在该程序中不使用 PORTB=0x00; DDRB=0x00; PORTC=0x00; DDRC=0x00; PORTD=0x00; DDRD=0x00; PORTE=0x00; DDRE=0x00; //设置定时器0的时钟来源为系统晶体 //设置计数周期为8000KHZ,清空计数寄存器 TCCR0=0x00; TCNT0=0x00; OCR0=0x00; //设置定时器1的时钟来源为系统晶体 //设置计数周期为1000KHZ,清空计数寄存器 TCCR1A=0x00; TCCR1B=0x02; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; //使能定时器 TIMSK=0x82; // 串口模数据:8个数据位,1个停止位,无奇偶效验 // 串口使能:发送、接收 // 串口模式:异步 // 串口速率:9600 UCSRA=0x02; UCSRB=0x18; UCSRC=0x86; UBRRH=0x00; UBRRL=0x34; //设置模拟比较器 ACSR=0x80; //使能看门狗,设置喂狗周期为 时钟/2048 WDTCR=0x1F; WDTCR=0x0F; // 打开总中断 #asm("sei") delay_ms(500); putchar(0x0d); putchar(0x0a); putsf("***********************************\r"); putsf("* 3路舵机驱动小程序 *\r"); putsf("* 顺德职业技术学院 机电工程系 *\r"); putsf("* 罗建章 *\r"); putsf("***********************************\r"); while (1) { count=0; putsf("输入舵机编号(1~3):"); putchar(0x0d); n1:i=getchar(); if((i
#include<at89x52.h> #include<INTRINS.h> #define uint unsigned int #define uchar unsigned char #define ulong unsigned long #define CLOCK P1_0 #define D_IN P1_1 #define D_OUT P1_2 #define _CS P1_3 sbit g1=P2^7; sbit g2=P2^1; sbit g3=P2^3; sbit g4=P2^5; ulong AD_ad1,AD_ad2; float JiZhun_AD=2.5; float AD_Data=0.0; ulong AD_ad=0; char chi; unsigned char code table[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; void delay02s(void) { unsigned char i,j,k; for(i=1;i>0;i--) for(j=10;j>0;j--) for(k=200;k>0;k--); } uint read1543(uchar port) { uint ad; uint i; uchar al=0,ah=0; CLOCK=0; _CS=0; port<<=4; for (i=0;i<4;i++) //将四位通道地址送1543 { D_IN=(bit)(port&0x80);CLOCK=1;CLOCK=0; port<<=1; } for (i=0;i<6;i++) //填6个CLOCK信号 { CLOCK=1;CLOCK=0; } _CS=1; _nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); _nop_();_nop_();_nop_(); _CS=0; //等待AD转换结束 _nop_();_nop_();_nop_(); for (i=0;i<2;i++) //D9,D8 { D_OUT=1;CLOCK=1;ah<<=1; if (D_OUT) ah +=0x01; CLOCK=0; } for (i=0;i<8;i++) //取出D7--D0 { D_OUT=1;CLOCK=1;al <<= 1; if (D_OUT) al +=0x01; CLOCK=0; } _CS=1; ad = (uint)ah; ad <<= 8; ad +=(uint)al; // return(ad); } void main() { TMOD=0x01; TH0=(65535-20000)/255; TL0=(65535-20000)%255; EA=1;ET0=1;TR0=1; while(1) { P0=table[(AD_ad)]; g1=1; delay02s(); g1=0; P0=table[(AD_ad/10)]; g2=1; delay02s(); g2=0; P0=table[(AD_ad/100)]; g3=1; delay02s(); g3=0; P0=table[(AD_ad/1000)]|0X80; g4=1; delay02s(); g4=0; } } zhongduan()interrupt 1 { TH0=(65535-20000)/255; TL0=(65535-20000)%255; chi++; if(chi==50) { chi=0; AD_ad1 = read1543(0); // (通道0电压正端) AD_Data = ((float)AD_ad1)*JiZhun_AD*2/1024+0.15005;//0.15经过实测需要加0.15减少误差 AD_ad =((AD_Data-2.68)/0.185)*1000; } }
#include<reg52.h> unsigned char code Segment[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; //数码管段码表0~9,带小数点的段码&0x7f unsigned char DispBuf_Clk[4] = {0,0,0,0}; //数码管显示缓冲区_时钟 unsigned char DispBuf_Sec[4] = {0,0,0,0}; //数码管显示缓冲区_秒表 unsigned char DispBuf_Tim[4] = {0,0,0,0}; //数码管显示缓冲区_倒计时 sbit Key1 = P2^4; sbit Key2 = P2^5; sbit Key3 = P2^6; sbit Key4 = P2^7; unsigned char KeyNum; unsigned char Fn = 0; //功能切换键键值(Key1) unsigned char Cursor = 1,Cursor1 = 0x00,Cursor2 = 0x00,Cursor3 = 0x00,Cursor4 = 0x00; //闪烁光标位置 unsigned char blink_cnt = 0; unsigned char clk_cnt = 0; unsigned char Clk_data; unsigned int sec; unsigned int tim = 100; unsigned int temp = 0; sbit S1 = P2^0; //数码管1位选信号,低电平有效 sbit S2 = P2^1; //数码管2位选信号,低电平有效 sbit S3 = P2^2; //数码管3位选信号,低电平有效 sbit S4 = P2^3; //数码管4位选信号,低电平有效 sbit LEDH = P3^5; //AH报警,低电平时亮 sbit LEDL = P3^4; //AL报警,低电平时亮 bit sec_en; bit tim_en; void delayus(unsigned int _t) { while(-- _t); } void delay(unsigned char t) //延时函数 t毫秒 { unsigned int i,j; for(i = 0; i < t; i++) for(j = 0; j < 500; j++); } void Init() //初始化函数 { EA = 1; //开总中断 TMOD = 0x11; //T0、T1均工作在方式1 RCAP2H=(65536-1000)/256; RCAP2L=(65536-1000)%256; //T2用于扫描数码管和键盘,扫描频率=1s/(10000*2us)=50Hz ET2 = 1; //允许定时器2中断 TR2 = 1; //启动定时器2 TH0 = 0x3C; //T0定时时间100ms TL0 = 0xB0; ET0 = 1; // TR0 = 1; TH1 = 0x3C; //T1定时时间100ms TL1 = 0xB0; ET1 = 1; TR1 = 1; } void WriteBuf(unsigned int Val) //写缓冲区函数 { unsigned char val1,val2,val3,val4; //缓冲区内的四个数 val1 = Val/1000; //取出千位 val2 = (Val%1000)/100; //取出百位 val3 = ((Val%1000)%100)/10; //取出十位 val4 = Val%10; //取出个位 switch(Fn) { case 0: { DispBuf_Clk[0] = val1; DispBuf_Clk[1] = val2; DispBuf_Clk[2] = val3; DispBuf_Clk[3] = val4; break; } case 1: { DispBuf_Sec[0] = val1; DispBuf_Sec[1] = val2; DispBuf_Sec[2] = val3; DispBuf_Sec[3] = val4; break; } case 2: { DispBuf_Tim[0] = val1; DispBuf_Tim[1] = val2; DispBuf_Tim[2] = val3; DispBuf_Tim[3] = val4; break; } default:break; } } void DispBuf_C() //显示缓冲区函数 { P0 = 0xff; S1 = 0; P0 = (Segment[DispBuf_Clk[0]] " C

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值