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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

【OS学习笔记】八 实模式:编写主引导扇区代码-另一种更高效的写法

發布時間:2023/12/10 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【OS学习笔记】八 实模式:编写主引导扇区代码-另一种更高效的写法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

學習交流加

  • 個人qq:
    1126137994
  • 個人微信:
    liu1126137994
  • 學習交流資源分享qq群:
    962535112

上一篇文章,我們用比較原始的方法編寫了主引導扇區的代碼。點擊鏈接查看上一篇文章:編寫主引導扇區代碼

本片文章將學習以下內容:

  • 用一種不同的分段方法,從另一個不同的的角度理解處理器的分段內存訪問機制
  • 使用循環和條件轉移指令來優化上一篇文章的主引導扇區代碼

文章目錄

  • 1、代碼清單
  • 2、代碼分析
  • 3、編譯運行
  • 4、總結

1、代碼清單

首先先貼上代碼。50行代碼,不長。看到匯編不要害怕!!!后面會一步一步分析這個匯編代碼的每一條指令的意思。

;代碼清單6-1;文件名:c06_mbr.asm;文件說明:硬盤主引導扇區代碼; jmp near startmytext db 'L',0x07,'a',0x07,'b',0x07,'e',0x07,'l',0x07,' ',0x07,'o',0x07,\'f',0x07,'f',0x07,'s',0x07,'e',0x07,'t',0x07,':',0x07number db 0,0,0,0,0start:mov ax,0x07c0 ;設置數據段基地址 mov ds,axmov ax,0xb800 ;設置附加段基地址,也就是將ES寄存器指向顯存的起始地址 mov es,axcld ;方向清零標志,將DF標志位清零,代表傳送是正向的mov si,mytext ;SI與DS組成數據段的地址 DS:SI 代表數據的真實物理地址 mov di,0 ;DI與ES組成顯存的物理地址 ES:DI 代表顯存的真實物理地址mov cx,(number-mytext)/2 ;實際上等于 13rep movsw ;循環movsw,直到cx寄存器內容為0(rep指令代表反復傳送);得到標號所代表的偏移地址mov ax,number;計算各個數位mov bx,axmov cx,5 ;循環次數 mov si,10 ;除數 digit: xor dx,dxdiv simov [bx],dl ;保存數位inc bx ;使bx寄存器里的值加1loop digit;顯示各個數位mov bx,number ;將number的匯編地址傳送給BX寄存器mov si,4 ;bx+si 得到字符串的每一個字符,SI從4遞減到0,這是由于要先顯示萬位上的數字show:mov al,[bx+si]add al,0x30 ;得到它對應的ASCII碼mov ah,0x04 ;對應的顏色屬性mov [es:di],ax ;AX中是一個完整的字,前8位是顯示屬性值,后8位是字符的ASCII碼add di,2 ;DI寄存器在之前用過,現在在“Label offset:” 字符串后面,剛好我們想讓number的匯編地址在這里顯示dec si ;SI-1,從number代表的匯編地址的萬位到個位,dec指令會影響SF標志位,當SI寄存器的值為0的時候,SF的標志位置1jns show ;判斷SF標志位是否為0,當SF標志位不為0,繼續執行show處的代碼。當SF標志位為0,則跳過這條指令執行下一條指令。mov word [es:di],0x0744 ;高字節0x07是黑底白字的屬性,低字節0x44是字符‘D’的ASCII碼jmp near $ ;相當于 infi: jmp near infitimes 510-($-$$) db 0 ; 計算512字節中,需要填滿的字節有哪些。db 0x55,0xaa ;一個有效的主引導扇區,最后兩字節必須是0x55 0xaa

2、代碼分析

堅持看完,一定能看懂!!!

  • 8行-9行:這里聲明了非指令的數據。一般來說,所有處理器指令都是按順序存放,在他們中間不允許夾雜非指令的數據。但是如果有辦法讓處理器不執行這些數據,則又另當別論。如第6行的代碼。

這兩行聲明的是要在顯示屏上顯示的數據:"Label offset: ",其中0x07是每個字符的顯示屬性值。

  • 6行:它是一條轉移指令。讓處理器跳轉到標號start處開始執行。這就避開了數據區。
  • 13-14行:設置數據段的基地址。DS代表數據段的基地址。

這里為什么是0x07c0呢?

由上幾篇文章學過的知識知道,主引導扇區程序加載時,被加載到的位置是0x0000:0x7c00.也就是物理地址:0x07c00 這其實就是將整個物理地址空間看成是基地址0x0000,偏移地址0x7c00的分段方式。

這樣的話,CPU每次訪問內存的時候總是要加上0x7c00這個偏移地址。但是程序中一般訪問內存的指令非常多,每一條都加上0x7c00很不現實。

但是Intel處理器的分段策略很靈活。邏輯地址0x0000:0x7c00對應的物理地址是0x07c00 ,而該地址又是另一個邏輯地址0x07c0:0x0000的地址。如下圖是以兩個邏輯段的視角看待同一個內存區域。

我們可以將512字節的區域看成是一個單獨的段。段的基地址是:0x07c0 段長512字節。注意,該段的最大長度是64KB,但是這里我們實際上只用了512字節。盡管BIOS是將主引導扇區加載到物理地址0x07c00處,但是我們卻可以認為它是從0x07c0:0x0000處開始加載的。

所以13-14行將數據段寄存器DS指向0x07c0

  • 16-17行:使附加段寄存器ES的內容指向顯存的基地址0xb800
  • 19-23行:循環movsw,直到cx寄存器內容為0(rep指令代表反復傳送)。這里是循環將DS:SI所指向的數據傳送到ES:DI所指定的顯示緩沖區。

循環movsw與movsb指令執行時,將DS:SI所指向的數據傳送到ES:DI所指定地址。同時每傳送一次 ,CX寄存器的內容減一。

rep代表循環movsw,直到寄存CX的內容為0為止。所以22行中,計算出數據的字節數,并將其傳送到CX寄存器。

20行將SI指向數據區的首地址,SI與DS組成數據段的地址 DS:SI 代表數據的真實物理地址

21行將0給DI寄存器,DI與ES組成顯存的物理地址 ES:DI 代表顯存的真實物理地址。很明顯,我們是從顯存的0偏移地址開始存數據。

19行,方向清零標志,將DF標志位清零,代表傳送是正向的。**正向的意思是傳送操作的方向是從內存的低地址端到搞地質端。**很明顯我們是正向傳送。

  • 26行:我們還是想像上一篇文章一樣,顯示字符串后將number這個標號的數值顯示出來。所以先將number標號的匯編地址傳送給AX寄存器保存。后面會用。

  • 29-37行:還記得上一篇文章是如何分解number的各個數位的么?如果不記得,請點擊鏈接查看:上一篇文章 上一篇文章是一個一個分解然后保存的。這里有所改變。使用了循環,可以讓我們少寫很多代碼。這里就不多說了,不懂的看上一篇文章,這個循環也很好理解,loop這個指令將循環次數CX減一,指導CX等于0為止。

  • 40-49行:顯示標號number的匯編地址的各個數位。同理,如何顯示各個數位,可以查看上一篇文章。這里只是將重復的代碼,寫成了循環的形式。

jns這個指令判斷SF標志位是否為0,當SF標志位不為0,繼續執行show處的代碼。當SF標志位為0,則跳過這條指令執行下一條指令。

dec指令會影響SF標志位,當SI寄存器的值為0的時候,SF的標志位置1

這里唯一需要注意的是低端字節序傳送的時候,寄存器的低字節傳送到顯示緩沖區的低地址部分,寄存器的高字節傳送到顯示緩沖區的高地址部分。如下圖所示:

  • 51行:顯示字符‘D’
  • 53行:死循環
  • 55行:計算512字節中,空字節有多少,然后將這些空字節填滿0

$ 代表當前行的匯編地址
$$ 代表當前段的起始地址。由于本程序沒有定義段,所以自成一個段,并且起始地址是0地址。

  • 56行:一個有效的主引導扇區,最后兩字節必須是0x55 0xaa

3、編譯運行

將我們匯編代碼編譯好的二進制bin文件寫到虛擬硬盤的主引導扇區中。啟動虛擬機,就會運行我們寫的代碼,運行結果如下:

今天的程序運行的很順利。

4、總結

了解匯編的運行機制,對以后深入學習高級語言,很有幫助:比如JVM。

筆記記得不是很全,像匯編的語法以及如何將代碼寫到虛擬硬盤的主引導扇區這些都沒有寫。如果又不懂的可以加我聯系方式一起交流。

學習探討加個人:
qq:1126137994
微信:liu1126137994

總結

以上是生活随笔為你收集整理的【OS学习笔记】八 实模式:编写主引导扇区代码-另一种更高效的写法的全部內容,希望文章能夠幫你解決所遇到的問題。

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