第七课 突破512字节限制--中

  上一节我们写了字符串打印的函数和软盘读取函数,在软盘读取函数中,我们是直接给定了要读的逻辑扇区号,这一节我们来实现一个查找文件的功能,也就是根据给定的文件名,在根目录区中查找指定的文件是否存在,涉及到文件名的查找,就会涉及到内存的比较,因此,我们需要实现两个函数,分别为内存比较函数和根目录区查找函数。

  整体的流程如下:

  首先将根目录区加载到内存中的指定位置上,这里面包含了一定数目的根目录项,而根目录项的前11个字节为文件名,因此,查找文件的工作就可以进行了,我们只需要将目标文件名和每一个根目录项的前11个字节进行比较即可,如果文件存在,必定会在某一个目录项中找到,只需将目录项的偏移位置通过寄存器返回即可。

  内存比较的示意图如下:

  需要用到的两个指令如下:

  比较指令:cmp cx, 0    ;  比较cx的值是否为零

  跳转:jz equal  ; 如果比较的结果为真,则跳转到equal处

  用于比较的汇编程序片段如下:

  

  1 org 0x7c00
  2
  3 jmp short start
  4 nop
  5
  6 define:
  7     BaseOfStack      equ 0x7c00
  8     RootEntryOffset  equ 19
  9     RootEntryLength  equ 14
 10
 11 header:
 12     BS_OEMName     db "D.T.Soft"
 13     BPB_BytsPerSec dw 512
 14     BPB_SecPerClus db 1
 15     BPB_RsvdSecCnt dw 1
 16     BPB_NumFATs    db 2
 17     BPB_RootEntCnt dw 224
 18     BPB_TotSec16   dw 2880
 19     BPB_Media      db 0xF0
 20     BPB_FATSz16    dw 9
 21     BPB_SecPerTrk  dw 18
 22     BPB_NumHeads   dw 2
 23     BPB_HiddSec    dd 0
 24     BPB_TotSec32   dd 0
 25     BS_DrvNum      db 0
 26     BS_Reserved1   db 0
 27     BS_BootSig     db 0x29
 28     BS_VolID       dd 0
 29     BS_VolLab      db "D.T.OS-0.01"
 30     BS_FileSysType db "FAT12   "
 31
 32 start:
 33     mov ax, cs
 34     mov ss, ax
 35     mov ds, ax
 36     mov es, ax
 37     mov sp, BaseOfStack
 38
 39     mov si, MsgStr
 40     mov di, DEST
 41     mov cx, MsgLen
 42
 43     call MemCmp
 44
 45     cmp cx, 0
 46     jz label
 47     jmp last
 48
 49
 50 label:
 51     mov bp, MsgStr
 52     mov cx, MsgLen
 53
 54     call Print
 55
 56 output:
 57     mov bp, MsgStr
 58     mov cx, MsgLen
 59     call Print
 60
 61 last:
 62     hlt
 63     jmp last
 64
 65
 66 ; ds:si --> source
 67 ; es:di --> destination
 68 ; cx    --> length
 69 ;
 70 ; return:
 71 ;        (cx == 0) ? equal : noequal
 72 MemCmp:
 73     push si
 74     push di
 75     push ax
 76
 77 compare:
 78     cmp cx, 0
 79     jz equal
 80     mov al, [si]
 81     cmp al, byte [di]
 82     jz goon
 83     jmp noequal
 84 goon:
 85     inc si
 86     inc di
 87     dec cx
 88     jmp compare
 89
 90 equal:
 91 noequal:
 92     pop ax
 93     pop di
 94     pop si
 95
 96     ret
 97
 98 ; es:bp --> string address
 99 ; cx    --> string length
100 Print:
101     mov ax, 0x1301
102     mov bx, 0x0007
103     int 0x10
104     ret
105
106 ; no parameter
107 ResetFloppy:
108     push ax
109     push dx
110
111     mov ah, 0x00
112     mov dl, [BS_DrvNum]
113     int 0x13
114
115     pop dx
116     pop ax
117
118     ret
119
120 ; ax    --> logic sector number
121 ; cx    --> number of sector
122 ; es:bx --> target address
123 ReadSector:
124     push bx
125     push cx
126     push dx
127     push ax
128
129     call ResetFloppy
130
131     push bx
132     push cx
133
134     mov bl, [BPB_SecPerTrk]
135     div bl
136     mov cl, ah
137     add cl, 1
138     mov ch, al
139     shr ch, 1
140     mov dh, al
141     and dh, 1
142     mov dl, [BS_DrvNum]
143
144     pop ax
145     pop bx
146
147     mov ah, 0x02
148
149 read:
150     int 0x13
151     jc read
152
153     pop ax
154     pop dx
155     pop cx
156     pop bx
157
158     ret
159
160 MsgStr db  "Hello World"
161 MsgLen equ ($-MsgStr)
162 DEST db  "Hello World"
163
164 Buf:
165     times 510-($-$$) db 0x00
166     db 0x55, 0xaa

  运行结果如下:

  上图的程序中,我们直接比较的字符串“Hello World”,如果比较成功,就将字符串打印出来。

  

原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9235638.html

时间: 2025-01-01 20:21:16

第七课 突破512字节限制--中的相关文章

第7课 - 突破512字节的限制(中)

突破限制的预备工作 整体思路 如何在根目录区中查找目标文件? 通过根目录项的前11个字节进行判断 内存比较 指定源起始地址(DS:SI) 指定目标起始地址(ES:DI) 判断在期望长度(CX)内每一个字节是否相等 汇编小贴士 汇编中的比较与跳转 比较: cmp cx, 0    :比较cx的值是否为0,并把结果记录到标志寄存器 跳转: jz equal          ; 如果比较为真(根据标志寄存器的值)就跳转到equal 访问栈空间中的栈顶数据 不能使用sp直接访问栈顶数据 通过其它通用寄

第六课 突破512字节的限制 上

前几节我们介绍了FAT12文件系统,制作了虚拟软盘文件a.img,并在Qt Creater中进行了文件内容的读取实验.那些读取都是使用外部的程序实现的,实际应用中,我们需要用主引导程序来实现文件的读写,主引导程序存在于主引导扇区MBR中,也就是说程序和文件是存在一张盘上的,而且这些主引导程序需要使用汇编语言实现.接下来,我们就来实现具有读取功能的主引导程序. 为了验证文件读取的正确性,我们需要在主引导程序中先实现一个字符串打印函数.BIOS已经将中断向量写到了内存的指定位置处,这其中就有能实现字

第八课 突破512字节的限制--下

上一节我们进行了文件的查找实验,文件查找成功了,这一节,我们将文件的内容加载进内存,再一次将整体的流程给出如下: 读取文件的内容时,我们需要根据FAT表找到存储文件内容的每一个扇区,然后进行内容的读取,在上一节中,我们将整个目录区的内容加载到了内存并根据文件名找到了所在的目录项,为了节省内存,我们将找到的目录项拷贝到另一片内存区域中,因为这个目录项中还有我们需要的内容,比如文件的起始扇区号等.而原来加载目录区的那一部分内存便可以另作他用,比如可以将FAT表加载到该区域. 目标文件的目录信息如下:

操作系统--突破512字节的限制

一.在突破512字节 Q:主引导程序中如何进行字符串打印?--直接打印A.BIOS中的字符串打印1.指定打印参数(AX=0x1301,BX=0x0007)--不借助循环2.指定字符串的内存地址(ES:BP=串地址)--通过段地址与段偏移来确定3.指定字符串的长度(CX=串长度)4.中断调用(int 0x10) B.汇编小贴士1.汇编中可以定义函数--函数名使用标签定义call function;函数体的最后一条指令为ret2.如果代码中定义了函数,那么需要定义栈空间主要用于保存关键寄存器的值:栈

第七课 进程通信

unix_c_07.txt================第七课 进程通信================一.基本概念------------1. 何为进程间通信~~~~~~~~~~~~~~~~~进程间通信(Interprocess Communication, IPC)是指两个,或多个进程之间进行数据交换的过程.2. 进程间通信分类~~~~~~~~~~~~~~~~~1) 简单进程间通信:命令行参数.环境变量.信号.文件.2) 传统进程间通信:管道(fifo/pipe).3) XSI进程间通信:

BeagleBone Black板第七课:GPIO编程控制

BBB板第七课:GPIO编程控制 在一上课我们通过IO函数做了简单的GPIO端口输出高低电平输出,实现对一个LED指示灯的点亮和关闭控制,本节将通过完整的C++程序,实现第四课Shell脚本的全部功能,实现两个LED指示灯的交替闪亮. 直接通过进入功能程序 1.实现echo 44 > export 打开端口功能 上一课简单测试中,通过手工在BBB板终端模式下打开gpio44端口可通过以下程序实现: #include <stdio.h> #define GPIO_DIR "/sy

NeHe OpenGL教程 第七课:光照和键盘

转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线教程的编写,以及yarn的翻译整理表示感谢. NeHe OpenGL第七课:光照和键盘 光照和键盘控制: 在这一课里,我们将添加光照和键盘控制,它让程序看起来更美观. 这一课我会教您如何使用三种不同的纹理滤波方式.教您如何使用键盘来移动场景中的对象,还会教您在OpenGL场景中应用简单的光照.这一课

[译文]JOAL教程 第七课 多普勒效应

[译文]JOAL教程 原文地址:http://jogamp.org/joal-demos/www/devmaster/lesson7.html 原文作者:Athomas Goldberg 译文:三向板砖 转载请保留以上信息. 本节课程对应的学习笔记:http://blog.csdn.net/shuzhe66/article/details/40393371 第七课多普勒效应 本文是DevMaster.net(http://devmaster.net/)的OpenAL教程对应的JOAL版本.C语言

7.7-UC-第七课:进程通信

================ 第七课  进程通信 ================ 一.基本概念 ------------ 1. 何为进程间通信 ~~~~~~~~~~~~~~~~~ 进程间通信(Interprocess Communication, IPC)是指两个, 或多个进程之间进行数据交换的过程. 2. 进程间通信分类 ~~~~~~~~~~~~~~~~~ 1) 简单进程间通信:命令行参数.环境变量.信号.文件. 2) 传统进程间通信:管道(fifo/pipe). 3) XSI进程间通信