日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【OS学习笔记】三十七 保护模式十:中断和异常的处理与抢占式多任务对应的汇编代码----主引导扇区代码

發布時間:2023/12/10 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【OS学习笔记】三十七 保护模式十:中断和异常的处理与抢占式多任务对应的汇编代码----主引导扇区代码 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文是以下幾篇文章對應的主引導扇區代碼匯編代碼:

  • 【OS學習筆記】三十四 保護模式十:中斷和異常區別
  • 【OS學習筆記】三十五 保護模式十:中斷描述符表、中斷門和陷阱門
  • 【OS學習筆記】三十六 保護模式十:通過中斷發起任務切換----中斷任務
;代碼清單17-1;文件名:c17_mbr.asm;文件說明:硬盤主引導扇區代碼 ;創建日期:2012-07-13 11:20 ;設置堆棧段和棧指針 core_base_address equ 0x00040000 ;常數,內核加載的起始內存地址 core_start_sector equ 0x00000001 ;常數,內核的起始邏輯扇區號 ;=============================================================================== SECTION mbr vstart=0x00007c00 mov ax,cs mov ss,axmov sp,0x7c00;計算GDT所在的邏輯段地址mov eax,[cs:pgdt+0x02] ;GDT的32位物理地址 xor edx,edxmov ebx,16div ebx ;分解成16位邏輯地址 mov ds,eax ;令DS指向該段以進行操作mov ebx,edx ;段內起始偏移地址 ;跳過0#號描述符的槽位 ;創建1#描述符,保護模式下的代碼段描述符mov dword [ebx+0x08],0x0000ffff ;基地址為0,界限0xFFFFF,DPL=00 mov dword [ebx+0x0c],0x00cf9800 ;4KB粒度,代碼段描述符,向上擴展 ;創建2#描述符,保護模式下的數據段和堆棧段描述符 mov dword [ebx+0x10],0x0000ffff ;基地址為0,界限0xFFFFF,DPL=00mov dword [ebx+0x14],0x00cf9200 ;4KB粒度,數據段描述符,向上擴展 ;初始化描述符表寄存器GDTRmov word [cs: pgdt],23 ;描述符表的界限 lgdt [cs: pgdt]in al,0x92 ;南橋芯片內的端口 or al,0000_0010Bout 0x92,al ;打開A20cli ;中斷機制尚未工作mov eax,cr0 or eax,1mov cr0,eax ;設置PE位;以下進入保護模式... ...jmp dword 0x0008:flush ;16位的描述符選擇子:32位偏移;清流水線并串行化處理器[bits 32] flush: mov eax,0x00010 ;加載數據段(4GB)選擇子mov ds,eaxmov es,eaxmov fs,eaxmov gs,eaxmov ss,eax ;加載堆棧段(4GB)選擇子mov esp,0x7000 ;堆棧指針;以下加載系統核心程序mov edi,core_base_addressmov eax,core_start_sectormov ebx,edi ;起始地址call read_hard_disk_0 ;以下讀取程序的起始部分(一個扇區);以下判斷整個程序有多大mov eax,[edi] ;核心程序尺寸xor edx,edxmov ecx,512 ;512字節每扇區div ecxor edx,edxjnz @1 ;未除盡,因此結果比實際扇區數少1dec eax ;已經讀了一個扇區,扇區總數減1@1:or eax,eax ;考慮實際長度≤512個字節的情況jz pge ;EAX=0 ?;讀取剩余的扇區mov ecx,eax ;32位模式下的LOOP使用ECXmov eax,core_start_sectorinc eax ;從下一個邏輯扇區接著讀@2:call read_hard_disk_0inc eaxloop @2 ;循環讀,直到讀完整個內核pge:;準備打開分頁機制。從此,再也不用在段之間轉來轉去,實在暈乎~ ;創建系統內核的頁目錄表PDTmov ebx,0x00020000 ;頁目錄表PDT的物理地址;在頁目錄內創建指向頁目錄表自己的目錄項mov dword [ebx+4092],0x00020003 mov edx,0x00021003 ;MBR空間有限,后面盡量不使用立即數;在頁目錄內創建與線性地址0x00000000對應的目錄項mov [ebx+0x000],edx ;寫入目錄項(頁表的物理地址和屬性) ;此目錄項僅用于過渡。;在頁目錄內創建與線性地址0x80000000對應的目錄項mov [ebx+0x800],edx ;寫入目錄項(頁表的物理地址和屬性);創建與上面那個目錄項相對應的頁表,初始化頁表項 mov ebx,0x00021000 ;頁表的物理地址xor eax,eax ;起始頁的物理地址 xor esi,esi.b1: mov edx,eaxor edx,0x00000003 mov [ebx+esi*4],edx ;登記頁的物理地址add eax,0x1000 ;下一個相鄰頁的物理地址 inc esicmp esi,256 ;僅低端1MB內存對應的頁才是有效的 jl .b1;令CR3寄存器指向頁目錄,并正式開啟頁功能 mov eax,0x00020000 ;PCD=PWT=0mov cr3,eax;將GDT的線性地址映射到從0x80000000開始的相同位置 sgdt [pgdt]mov ebx,[pgdt+2]add dword [pgdt+2],0x80000000 ;GDTR也用的是線性地址lgdt [pgdt]mov eax,cr0or eax,0x80000000mov cr0,eax ;開啟分頁機制;將堆棧映射到高端,這是非常容易被忽略的一件事。應當把內核的所有東西;都移到高端,否則,一定會和正在加載的用戶任務局部空間里的內容沖突,;而且很難想到問題會出在這里。 add esp,0x80000000 jmp [0x80040004] ;------------------------------------------------------------------------------- read_hard_disk_0: ;從硬盤讀取一個邏輯扇區;EAX=邏輯扇區號;DS:EBX=目標緩沖區地址;返回:EBX=EBX+512 push eax push ecxpush edxpush eaxmov dx,0x1f2mov al,1out dx,al ;讀取的扇區數inc dx ;0x1f3pop eaxout dx,al ;LBA地址7~0inc dx ;0x1f4mov cl,8shr eax,clout dx,al ;LBA地址15~8inc dx ;0x1f5shr eax,clout dx,al ;LBA地址23~16inc dx ;0x1f6shr eax,clor al,0xe0 ;第一硬盤 LBA地址27~24out dx,alinc dx ;0x1f7mov al,0x20 ;讀命令out dx,al.waits:in al,dxand al,0x88cmp al,0x08jnz .waits ;不忙,且硬盤已準備好數據傳輸 mov ecx,256 ;總共要讀取的字數mov dx,0x1f0.readw:in ax,dxmov [ebx],axadd ebx,2loop .readwpop edxpop ecxpop eaxret;-------------------------------------------------------------------------------pgdt dw 0dd 0x00008000 ;GDT的物理/線性地址 ;------------------------------------------------------------------------------- times 510-($-$$) db 0db 0x55,0xaa

總結

以上是生活随笔為你收集整理的【OS学习笔记】三十七 保护模式十:中断和异常的处理与抢占式多任务对应的汇编代码----主引导扇区代码的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。