您的位置:首页 > 运维架构 > Linux

写一个能装载硬盘数据到内存的MBR程序

2013-06-15 16:09 232 查看
我们已经学会了让自己的指令作为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 Linux
相关文章推荐