MBR笔记

bochs:1 00000000000e[WGUI ] Sim client size(0, 0) != stretched size(640, 480)!

bochs:2 b 0x7c00
bochs:3 c
00000003740i[BIOS ] $Revision: 1.166 $ $Date: 2006/08/11 17:34:12 $
00000319045i[KBD  ] reset-disable command received
00000321693i[PIDE ] new BM-DMA address: 0xc000
00000327577i[P2I  ] PCI IRQ routing: PIRQA# set to 0x0b
00000327593i[P2I  ] write: ELCR2 = 0x08
00000327613i[ACPI ] new irq line = 11
00000446187i[VBIOS] VGABios $Id: vgabios.c,v 1.66 2006/07/10 07:47:51 vruppert Exp $
00000446258i[BXVGA] VBE known Display Interface b0c0
00000446290i[BXVGA] VBE known Display Interface b0c4
00000449215i[VBIOS] VBE Bios $Id: vbe.c,v 1.58 2006/08/19 09:39:43 vruppert Exp $
00000759983i[BIOS ] ata0-0: PCHS=512/4/16 translation=none LCHS=512/4/16
00000800002i[WGUI ] dimension update x=720 y=400 fontheight=16 fontwidth=9 bpp=8
(0) Breakpoint 1, 0x0000000000007c00 in ?? ()
Next at t=957062

;中断与0x7c00   开始MBR程序
;关中断
(0) [0x0000000000007c00] 0000:7c00 (unk. ctxt): cli                       ; fa
bochs:4 n
Next at t=957063
(0) [0x0000000000007c01] 0000:7c01 (unk. ctxt): xor ax, ax                ; 31c0
bochs:5 n
Next at t=957064
;设置段寄存器
(0) [0x0000000000007c03] 0000:7c03 (unk. ctxt): mov ss, ax                ; 8ed0
bochs:6 n
Next at t=957065
;设置栈顶
(0) [0x0000000000007c05] 0000:7c05 (unk. ctxt): mov sp, 0x7c00            ; bc007c
bochs:7 n
Next at t=957066
;开中断
(0) [0x0000000000007c08] 0000:7c08 (unk. ctxt): sti                       ; fb
bochs:8 n
Next at t=957067
;设置数据段寄存器   就是把0x7c0 赋值给数据段寄存器  这里估计是源代码写重复了已经赋值了结果下面还用ax赋值给ds
;源代码中作者果然写重复了
;这里写重复了push和pop以及下面的都是已经把07c0h赋值给ds数据段寄存器了
 push 07c0h
 pop ds
 mov  ax, 07c0h       
 mov  ds, ax
;//////////////////////////////////////////////////分割线////////////////////////////////////

(0) [0x0000000000007c09] 0000:7c09 (unk. ctxt): push 0x07c0               ; 68c007
bochs:9 n
Next at t=957068
(0) [0x0000000000007c0c] 0000:7c0c (unk. ctxt): pop ds                    ; 1f
bochs:10
Next at t=957069
(0) [0x0000000000007c0d] 0000:7c0d (unk. ctxt): mov ax, 0x07c0            ; b8c007
bochs:11 n
Next at t=957070
(0) [0x0000000000007c10] 0000:7c10 (unk. ctxt): mov ds, ax                ; 8ed8
bochs:12 n
Next at t=957071
;加载ntldr 
;count - ntldr扇区总数   80000h/512-8=0x3f8
(0) [0x0000000000007c12] 0000:7c12 (unk. ctxt): push 0x000003f8           ; 6668f8030000
bochs:13 n
Next at t=957072
;src开始读取的扇区号
(0) [0x0000000000007c18] 0000:7c18 (unk. ctxt): push 0x00000008           ; 666808000000
bochs:14 n
Next at t=957073
;des - 存放数据的目的地址(物理内存地址)
(0) [0x0000000000007c1e] 0000:7c1e (unk. ctxt): push 0x00020000           ; 666800000200
bochs:15 n
Next at t=957074
;这里是call  LoadSector(int des,int src,int count);
;用c语言描述:

1 void LoadSector(int des,int src,int count) 2{ 3     int run = count / 64; //计算扇区的循环次数 为了提高效率不安扇区127的倍数取,取2的6次方64 4     int mod = count % 64; //计算剩余扇区 5     for(int i=0,i<run,i++) 6     { 7          ReadWriteSector(0x80,src,0,64,des,0x42); //每次读取64扇区 8          src = src +64; //重写计算扇区 9          des = des + 64*512; //重新计算目的地址 10     } 11     if(mod) //如果纯在剩余扇区,读取一次就ok了 12     { 13      ReadWriteSector(0x80,src,0,64,des,0x42); 14     } 15}

(0) [0x0000000000007c24] 0000:7c24 (unk. ctxt): call .+7 (0x00007c2e)     ; e80700
bochs:16 n
Next at t=1171020
;采用fastboot跳转至  0x2000:0003 如果是NTFS boot则跳转至0x2000:0000刚好执行 jmp RealStart 而fatboot则会忽略3B这条指令
(0) [0x0000000000007c27] 0000:7c27 (unk. ctxt): push 0x2000               ; 680020
bochs:17 n
Next at t=1171021
(0) [0x0000000000007c2a] 0000:7c2a (unk. ctxt): push 0x0000               ; 680000
bochs:18 n
Next at t=1171022
(0) [0x0000000000007c2d] 0000:7c2d (unk. ctxt): retf                      ; cb
bochs:19 n
Next at t=1171023
(0) [0x0000000000020000] 2000:0000 (unk. ctxt): jmp .+509 (0x00020200)    ; e9fd01
bochs:20

LoadSector实现:

1 void LoadSector(int des,int src,int count) 2{ 3     int run = count / 64; //计算扇区的循环次数 为了提高效率不安扇区127的倍数取,取2的6次方64 4     int mod = count % 64; //计算剩余扇区 5     for(int i=0,i<run,i++) 6     { 7          ReadWriteSector(0x80,src,0,64,des,0x42); //每次读取64扇区 8          src = src +64; //重写计算扇区 9          des = des + 64*512; //重新计算目的地址 10     } 11     if(mod) //如果纯在剩余扇区,读取一次就ok了 12     { 13          ReadWriteSector(0x80,src,0,64,des,0x42); 14     } 15}

LoadSector的nasm源代码:

1 void LoadSector( 2; int des,  3; int src,  4; int count); 5LoadSector: 6;{ 7 push  ebp   8 mov  ebp, esp  ;保存栈框架  这里是0x7c00-4-4-4-2=0x7bf2  进入LoadSector的三次push call LoadSector占2B 9  10 sub  esp, 0E4h  ;开辟栈空间0e4h=228 11 push  ebx   12 push  esi   13 push  edi   14  15 ;int run = count / 64; 16 mov  eax,dword [ebp+0Eh]  ;ebp+0eh为进入函数后的esp+14及最开始的push count 17 cdq                 ;扩展edx为eax的高位 18 and  edx, 3Fh  19 add  eax, edx  20 sar  eax, 6     ;右移6位及除以64 21 mov  dword [ebp-8], eax  ;保存循环次数ebp-8 22  23 ;int mod = count % 64; 24 mov  eax, dword [ebp+0Eh]  ;读取扇区数 这里就是将参数count的值传入给eax  就是最开始的ebp+14 25 and  eax, 8000003Fh   ;实现摸64操作 26 jns  .set_mod 27 dec  eax   28 or  eax,0FFFFFFC0h  29 inc  eax   30  31.set_mod:  32 mov  dword [ebp-14h], eax  ;64的余数放到ebp -  14h中  最开始开辟了228B的空间 33 ;for(int i=0; i<run; i++) 34 mov  dword [ebp-20h], 0  ;i的空间地址设置成为0 35 jmp  _read 36  37_loop: 38 mov  eax,dword [ebp-20h]  39 add  eax,1  40 mov  dword [ebp-20h],eax  41_read:    42    mov  eax,dword [ebp-20h]  ;将i的值给eax和次数比较 43 cmp  eax,dword [ebp-8]   ;eax和ebp-8及最开始的count比较 44 jge  _left     ;大于等于则跳转 退出循环 45 ;{ 46 ;ReadWriteSector(0x80, src, 0, 64, des, 0x42); 47 push  dword 42h 48 mov  eax, dword [ebp+6]  49 push  eax   50 push  dword 40h   51 push  dword 0     52 mov  ecx, dword [ebp+0Ah]  53 push  ecx   54 push  dword 80h   55 call  ReadWriteSector 56 add  esp, 24 57 ;src = src + 64; 58 mov  eax, dword [ebp+0Ah]  59 add  eax, 40h  60 mov  dword [ebp+0Ah], eax  61 ;des = des + 64*512; 62 mov  eax, dword [ebp+6]  63 add  eax, 8000h  64 mov  dword [ebp+6], eax  65 ;} 66 jmp  _loop 67 ;if(mod) 68_left: 69 cmp  dword [ebp-14h],0            70    je  .return 71 ;{ 72  ;ReadWriteSector(0x80, src, 0, mod, des, 0x42); 73 push  dword 42h  74 mov  eax, dword [ebp+6]  75 push  eax   76 mov  ecx, dword [ebp-14h]  77 push  ecx   78 push  dword 0     79 mov  edx, dword [ebp+0Ah]  80 push  edx   81 push  dword 80h   82 call  ReadWriteSector 83 add  esp, 24 84 ;} 85;} 86.return:    87    pop  edi   88 pop  esi   89 pop  ebx   90 add  esp, 0E4h  91 mov  esp, ebp  92 pop  ebp   93 ret 12 94 95 ReadWriteSector汇编代码 96相关的数据结构 97;Disk Address Packet 98struc DAP                         99 .PacketSize     resb  1     ;数据包的大小,固定为10h 100 .Reserved       resb  1     ;预留空间固定为1字节 101 .BlockCount     resw  1   ;0~127 要传输的扇区数目 102 .BufferOffset   resw  1     ;传输缓冲的偏移地址 103 .BufferSegment  resw  1    ;传输缓冲的地址段 104 .LBNLow         resd  1   ;0 105 .LBNHigh        resd  1  ; 106endstruc   107  108struc SectorFrame       109 .DriveNum        resd  1 ;表示读取数据所在的磁盘 110 .LBNLow          resd  1 ;要读取数据所在的骑士扇区号 111 .LBNHigh         resd  1 ; 112 .BlockCount      resd  1 ;一次读取的扇区数 113 .Buffer          resd  1    ;所读取数据存放的物理地址 114 .ReadWrite       resd  1 ;表示进行什么操作  读还是写 115endstruc 116 117  118;NTSTATUS  119;(_cdecl* ReadWriteSector)( 120; ULONG DriveNum,  121; ULONG LBNLow,  122; ULONG LBNHigh,  123; ULONG BlockCount,  124; PVOID Buffer,  125; ULONG ReadWrite); // Read=0x42,Write=0x43 126  127ReadWriteSector: 128    push  bp 129    mov  bp, sp 130    add  bp, 4 131    push  ds 132    push  si 133    push  bx 134  135    push  0 136    pop  ds 137      138 sub  sp, 16 139 mov  si, sp 140 mov  byte [si+DAP.PacketSize], 10h         141 mov  byte [si+DAP.Reserved], 0           142 mov  al,byte [bp+SectorFrame.BlockCount] 143 mov  byte[si+DAP.BlockCount], al            144 mov  byte[si+DAP.BlockCount+1], 0          145 mov  eax, dword[bp+SectorFrame.Buffer] 146    mov  bx, ax 147    and  bx, 0fh      148    mov  word[si+DAP.BufferOffset], bx         149    shr  eax, 4 150    mov  word[si+DAP.BufferSegment], ax         151    mov  eax, dword[bp+SectorFrame.LBNLow] 152    mov  dword[si+DAP.LBNLow], eax             153    mov  eax, dword[bp+SectorFrame.LBNHigh] 154    mov  dword[si+DAP.LBNHigh], eax            155    mov  ah, byte [bp+SectorFrame.ReadWrite]                                           156    mov  dl, byte [bp+SectorFrame.DriveNum]           157    int  13h 158    jc   .error 159    xor  eax, eax 160.error: 161    and  eax, 0000ffffh 162             163 add  sp, 16 164 pop  bx 165 pop  si 166 pop  ds 167  168 pop  bp 169 retn
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

Java爬虫之JSoup使用教程

title:Java爬虫之JSoup使用教程date:201812248:00:000800update:201812248:00:000800author:mecover:https://imgblog.csdnimg.cn/20181224144920712(https://www.oschin