; 读磁盘 MOV AX,0x0820 MOV ES,AX MOV CH,0 ; 柱面0 MOV DH,0 ; 磁头0 MOV CL,2 ; 扇区2 MOV AH,0x02 ; AH=0x02 : 读盘 MOV AL,1 ; 1个扇区 MOV BX,0 MOV DL,0x00 ; A驱动器 INT 0x13 ; 调用磁盘BIOS JC error
JC是jump if carry的缩写,如果进位标志 (carry flag)是1的话就跳转,
INT 0x13,这个中断的说明参观:https://blog.csdn.net/weixin_37656939/article/details/79684611,书上的网站访问不了。
AH=0x02(读盘)
AH=0x03(写盘)
AH=0x04(校验)
AH=0x0c (寻道)
AL=处理对象的扇区数,(只能同时处理连续的扇区)
CH=柱面号
CL=扇区号
DH=磁头号
DL=驱动器号
ES:BX=缓冲地址(校验及寻道时不使用)
返回值
FLACS.CF=0: 没有错误,AH=0 AL=传输的扇区数(这里不知道是不是书上印错了,应该是FLAGS)
FLAGS.CF=1: 有错误,错误号存入AH内(与重置功能一样)
这里是AH=0X02,所以是读盘
CF(carry flag)是一个只有一位信息的寄存器,这种只有一位的寄存器称为标志(flag),CF本是用来表示有没有进位的,但因为简单易用,所有其它地方也经常用到,这里就是表示函数调用 是否有错。
软盘结构:
80个柱面(0-79),每个柱面18个扇区(sector)(1-18)每个扇区512字节,两个磁头(0 正面和1 背面),所以一张软盘容量是80*18*512*2=1 474 560 字节 = 1440KB
含有IPL的启动区位于柱面0,磁头0,扇区1(C0-H0-S1) ,它的下一个扇区是 C0-H0-S2, 这里要加载的就是这个。
注意:软盘是按扇区读取,但是内存是按字节对地址编号的。
ES:BX=缓冲地址,这个地址就是一个内存地址,表示我们要把从软盘上读出的数据装载到内存的哪个位置,BX是16位寄存器,只能表示0-0xffff的值,也就是0-65535,最大才64K。只用一个寄存器的话就只能用64K的内存,
EBX 是32位,能处理4G内存,0-0xffffffff ( 0 - 4294967295字节)即4194304KB = 4096MB = 4GB
而早期没有EBX寄存器,所以设计了一个起辅助作用的段寄存器,使用段寄存器时,以[ES:BX]方式表示内存地址,即ES*16+BX ,如果ES取0xffff,BX也取0xffff,则为 0xffff * 16 + 0xffff = 65535*16 + 65535 = 1114095Byte = 1087KB,这样就可以访问1MB内存。
这里ES=0X0820, BX=0,所以软盘的数据将被装载到内存中的0x8200到0x83ff(512字节,一个扇区)的地方。0x8000 - 0x81ff这512字节是留给(copy)启动区的,要将启动区的内容读到那里。0x7c00 - 0x7dff(512字节)用于启动区。
内存分布图:
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
不管要指定内存的什么地址,都必须同时指定段寄存器,如省略会把“DS”作为默认的段寄存器。
MOV CX, [1234] 其实是MOV CX, [DS: 1234]的意思。
MOV AL, [SI] 就是 MOV AL, [DS: SI] 的意思
所以DS必须预先指定为0,否则地址的值就要加上这个数的16倍,就会读写到其它地方,引起混乱。
原文:https://www.cnblogs.com/johnjackson/p/12319036.html