1. 背景
本文介绍了“调用元神操作系统API向U盘扇区写数据”的程序实现及测试结果。
2. 方法
(1)调用元神操作系统API读U盘扇区
本部分内容已在前面的文章中进行介绍,详细内容请参考“编写程序调用元神操作系统的API”。
(2)调用元神操作系统API写U盘扇区
本例通过调用系统API来向U盘扇区写数据,代码如下所示:
sector_buff: times 512 db 1
demo_write_usb:
pusha
mov edi, API_PARAM
mov dword [fs:edi], API_WRITE_USB_SECTOR
mov dword [fs:edi+4], 2 ;2 parameters
mov dword [fs:edi+8], 3 ;parameter_1: sector no.
xor eax, eax
mov ax, ds
add eax, SEG_BASE
mov bh,byte [fs:eax+7]
mov bl,byte [fs:eax+4]
shl ebx,16
mov bx,word [fs:eax+2]
add ebx, sector_buff
mov dword [fs:edi+12], ebx ;parameter_2: start address of buffer
call pword [fs:OS_API]
popa
ret
代码中先定义了变量sector_buff,用于存储要写入U盘扇区的数据,本例为512个1。然后在代码中如前述文章所描述的那般进行参数设置,将API类型设置为API_WRITE_USB_SECTOR,该API需要2个参数,第一个参数是要写数据的扇区的LBA号(本例要写3号扇区),第二个参数为保存要写入数据的缓冲区起始地址(本例为sector_buff)。设置好参数后通过“call pword [fs:OS_API]”进行API调用、完成写扇区操作。
本例和前述系统API调用的主要差别在于新的API类型和缓冲区地址转换,新增的定义如下:
SEG_BASE equ 0x00040000
API_WRITE_USB_SECTOR equ 0x00000007
其中,SEG_BASE表示的是保护模式下GDT的起始地址,通过它和DS中的段选择子定位到本demo程序加载到内存的位置,并提取出其起始地址,再加上sector_buff的偏移,得到该变量的真实地址,最后才将该地址赋给调用参数。
(3)附属程序
本例先读取3号扇区的内容并打印到屏幕上,然后将新的数据写入3号扇区,最后再重新读取3号扇区并打印到屏幕上,代码如下所示:
use32
START:
pusha
call demo_read_usb
call demo_write_usb
call demo_read_usb
popa
iret
include 'api_def.inc'
OS_API equ 0x00030C16
API_PARAM equ 0x03000000
SEG_BASE equ 0x00040000
cursor_x equ 0x02004B10
cursor_y equ 0x02004B12
代码中的demo_read_usb函数直接采用前述文章中的实现代码即可,具体可参考前述文章。
(4)运行程序
将以上的代码保存为DEMO.ASM,编译生成DEMO.BIN,并将该可执行文件复制到装有元神操作系统的U盘中,之后用该U盘开机进入元神系统并输入命令“ZX DEMO.BIN”执行程序如下:
可以看到,U盘3号扇区的内容已经成功修改,改成了全1的512个字节数据。
3. 总结
本文介绍的方法成功地向U盘的目标扇区写入了数据。但是,写扇区须谨慎,以免错写某些文件已经占用的扇区从而导致文件出错。