编写程序调用元神操作系统的API

1. 背景

本文介绍了元神操作系统API的调用,并详细介绍了“调用元神系统API读取磁盘扇区”程序的编写以及测试结果。

2. 方法

(1)元神操作系统API的调用方法

元神操作系统0.4版beta4开始提供了对OS功能的调用,调用相关的定义如下:

OS_API equ 0x00030C16
API_PARAM equ 0x03000000

其中,OS_API定义的是API调用的入口,设置好要调用的API类型及其参数之后,直接call该入口即可实现系统API调用。而要调用的API类型及参数则由API_PARAM指定,其指定的格式如下:

PARAM_1: 要调用的API类型
PARAM_2:传给API的参数个数
PARAM_3:传给API的第一个参数
PARAM_4:传给API的第二个参数(如果有的话),依次类推

其中,每个PARAM都是4字节大小。例如,要读取优盘的第一个扇区,其API_PARAM设置如下:

PARAM_1 = API_READ_USB_SECTOR
PARAM_2 = 2
PARAM_3 = 0
PARAM_4 = 扇区数据存放地址

由此可知,要调用的API是“读取优盘扇区”,传递2个参数给该API,第一个参数为0(表示读取第一个扇区,即0号扇区),第二个参数是接收扇区数据的内存地址。

(2)编写程序读取优盘的0号扇区

本例使用汇编语言编写,代码如下所示:

use32

START:
	pusha
	
	
	call demo_read_usb
	
	popa
	iret

include 'api_def.inc'

cursor_x equ 0x02004B10
cursor_y equ 0x02004B12
OS_API equ 0x00030C16
API_PARAM equ 0x03000000

sector_buff: times 512 db 0
demo_read_usb:
	pusha
	mov edi, API_PARAM
	mov dword [fs:edi], API_READ_USB_SECTOR
	mov dword [fs:edi+4], 2		;2 parameters
	mov dword [fs:edi+8], 0		;param_1: sector no.
	xor eax, eax
	mov ax, ds
	shl eax, 4
	add eax, sector_buff
	mov dword [fs:edi+12], eax	;param_2: start address of buffer to store result

	call pword [fs:OS_API]
	
	mov eax, 512
	movzx ebx, word [fs:cursor_y]
	movzx ecx, word [fs:cursor_x]
	mov esi, [fs:edi+12]
	call print_bytes_hex
	
	add word [fs:cursor_y], 20

	popa
	ret


;print hex bytes
;input:
;	eax: byte count to print
;	ebx: y coordinate to print (from 0)
;	ecx: x coordinate to print (from 0)
;	esi: buffer storing data to print
print_bytes_hex:
	pusha
	imul edi,ebx,80*2
	add edi,ecx
	add edi,ecx
	
	mov ecx,eax
	mov ah,0x0F		;should use edx in stack
 .next_char:
	mov bl,byte [fs:esi]
 .hex_char:
	mov al,bl
	and al,0x0F
	add al,0x30
	cmp al,0x39
	jbe .num_char
	add al,'A'-0x30-10
 .num_char:
	mov [gs:edi+2],ax
	shr ebx,4
	mov al,bl
	and al,0x0F
	add al,0x30
	cmp al,0x39
	jbe .num_char2
	add al,'A'-0x30-10
 .num_char2:
	mov [gs:edi],ax
	mov al,' '
	mov [gs:edi+4],ax
	add edi,6
	inc esi
	loop .next_char
	
	popa
	ret

将以上代码保存为DEMO.ASM,编译生成DEMO.BIN,并将该可执行文件复制到装有元神操作系统的U盘中,之后用该U盘开机进入元神系统并输入命令“ZX  DEMO.BIN”执行该程序如下:

这里以二进制显示的就是U盘0号扇区的数据,对应到示例程序,语句“call pword [fs:OS_API]”完成的就是系统API调用,该语句之前的部分是对调用参数的设置,之后的部分是对调用结果的输出显示。参数设置部分在本章开头部分已经进行介绍,需要补充的是数据存储地址,该地址需要是全局地址,而非本应用程序的地址,所以将其和数据段寄存器DS的值结合在一起,之后再传给参数。

至于最后的输出显示函数print_bytes_hex,其以十六进制字节序列的形式完成输出,每两个字节之间以空格分隔。要输出的字节数通过EAX寄存器传递,本例指明要输出512字节,因为一个扇区的大小为512字节。将显示结果向下滚动查看完整的扇区数据如下:

从该图能看出,读出的的确是0号扇区的数据,其最后两个字节“55 AA”是该扇区的结束标志。

另外,本例中涉及到的文件api_def.inc是用于定义元神操作系统API类型的,目前为止数据较少,如下所示:

API_READ_USB_SECTOR	    equ	0x00000003
API_READ_DISK_SECTOR	equ	0x00000004

第一句表示读取优盘的扇区,第二句表示读取硬盘/磁盘的扇区。

(3)编写程序读取磁盘的0号扇区

本例展示读取硬盘/磁盘的第一个扇区的API调用,其大部分和上例相同,含有差异的主要部分如下所示:

use32


START:
	pusha
	
	call demo_read_disk
	
	popa
	iret

include 'api_def.inc'

cursor_x equ 0x02004B10
cursor_y equ 0x02004B12
OS_API equ 0x00030C16
API_PARAM equ 0x03000000

sector_buff: times 512 db 0

demo_read_disk:
	pusha
	mov edi, API_PARAM
	mov dword [fs:edi], API_READ_DISK_SECTOR
	mov dword [fs:edi+4], 2		;2 parameters
	mov dword [fs:edi+8], 0		;param_1: sector no.
	xor eax, eax
	mov ax, ds
	shl eax, 4
	add eax, sector_buff
	mov dword [fs:edi+12], eax	;param_2: start address of buffer to store result

	call pword [fs:OS_API]
	
	mov eax, 512
	movzx ebx, word [fs:cursor_y]
	movzx ecx, word [fs:cursor_x]
	mov esi, [fs:edi+12]
	call print_bytes_hex
	
	add word [fs:cursor_y], 20

	popa
	ret

由于本例和上例都是读取磁盘扇区,区别仅在于一个读的是U盘、另一个读的是硬盘,所以仅改变API类型即可,本例将类型设置为API_READ_DISK_SECTOR。

如上例那般编译运行程序,结果如下图所示:

和上例一样,本例扇区数据的最后两个字节仍然是“55 AA”。两例都是读取磁盘的第一个扇区,但U盘是没有分区的,而硬盘是经过分区的,所以可以看到本例含有两个分区表项,具体内容可以查阅MBR、DBR、分区表等的详细文章阅览。

3. 总结

元神操作系统API的调用方式比较统一,调用接口设计为唯一的,将API及其参数都作为数据进行传递,改动起来比较灵活,而且不会因为过量的参数导致堆栈溢出。

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

De-Chang Wang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值