我们已经学会了让自己的指令作为MBR程序运行,但是它只能打印一个字符。这次我们要做的事是让我们的指令从硬盘上读取一块数据到内存里。
这里要用到另一个bios中断。 什么是bios中断?中断就是让cpu暂停目前的指令,而转去执行另一块指令,执行完后再返回来继续执行目前的指令。而bios中断是基本的输入/输出中断,当我们的指令中包含一条中断指令(比如上一篇中的int 10h),cpu就会根据后面的中断号转去执行相应的指令,如果中断号为10h,cpu就去执行13h对应的那一块指令,在那一块指令里,有各种判断语句,比如如果判断到寄存器ah的值为0xe,那么它就执行显示操作,将当前al里asc码对应的字符显示在输出设备(显示器)上,至于如何显示,那就是另外需要学习的了,其原理也很容易理解。但是现在我们不需要关心,我们只需要知道,如果想在显示器上显示字符X,就先将ah的值设为0xe,再将al的值设为X对应的asc码,再调用10h号中断就可以了。 这次我们要用到的是0x13号中断。需要设寄存器ah的值为42h,设寄存器DL的值为0x81,然后在给DS和SI设值,最后再给以DS:SI开始的16个字节的内存设置,当这一切都设好后,就调用0x13号中断,那么cpu就会将硬盘指定扇区的数据读入内存上指定的地方,这些指定的内容正是我们前面所设置的。 下面的代码以u盘方式运行后,u盘的mbr先将自己拷贝到令一块内存,然后跳过去继续执行,将硬盘的mbr读入内存0x7c00的地方,然后跳到0x7c00处执行 mov cx,512
mov ax,0
mov ds,ax
mov si,0x7c00
mov di,0x8c00
copy:
mov dx,[si]
mov [di],dx
inc si
inc di
loop copy
jmp 0x1019 ;jmp to 0x8c19. current add:0x16. next ins add:0x19. ip after fetch:0x7c19 operands:0x1019-0x19=0x1000.
;ip after exe:0x7c19+0x1000=0x8c19
mov ah,0xe ;print a smile face
mov al,1
int 10h
read:
mov ah,0x42
mov dl,0x81
mov si,0x0
mov ds,si
mov si,0x8000
mov byte [si],0x10
mov word [si+2],0x1
mov word[si+4],0x7c00
mov word[si+6],0x0
mov dword[si+8],0x0
mov dword[si+12],0x0
int 0x13
jmp -0x1000 ;ip after fetch:0x8c7d. next ins add:0x7d. X=desAdd - ipAfterFetch + nexInsAdd
end:
jmp end
printHex:
mov ah,0xe
cmp al,10
jnb notBelowTen
add al,48
jmp print
notBelowTen:
add al,55
print:
int 0x10
ret
times 0200h - 2 - ($ - $$) db 0 ; NASM directive: zerofill up to 510 bytes
dw 0AA55h
; Magic boot sector signature
db "ABCDEFG"
|
写一个能装载硬盘数据到内存的MBR程序
最新推荐文章于 2024-01-11 21:00:00 发布