30天自制操作系统——Day8实验报告
文章目錄
- 一. 主要內(nèi)容
- 1、 內(nèi)容1:鼠標解讀(1)
- 2、 內(nèi)容2: 稍事整理
- 3、內(nèi)容3: 鼠標解讀(2)
- 4、 內(nèi)容4: 移動鼠標指針
- 5、 內(nèi)容5: 通往32位模式之路
- 二、遇到的問題及解決方法
- 1、 描述問題1:理解鼠標數(shù)據(jù)第一階段的if判斷操作
- 2、 描述問題2:理解ECX寄存器+3并向左移位的意義
一. 主要內(nèi)容
1、 內(nèi)容1:鼠標解讀(1)
重點總結(jié):在Day7中,我們已經(jīng)從鼠標中取得了數(shù)據(jù)。現(xiàn)在我們要來解讀這些數(shù)據(jù)
(1)bootpack.c
1、 函數(shù)功能:讀取鼠標數(shù)據(jù)
a. 首先把最初讀到的0xfa舍棄掉
b. 將從鼠標讀取的數(shù)據(jù)按照3個字節(jié)為一組,當(dāng)數(shù)據(jù)累積到3個字節(jié),就把它顯示在屏幕上
(2)結(jié)果
1、 結(jié)果解讀
屏幕上會顯示“08 00 02”等三字節(jié)數(shù)字。
第一個字節(jié):”08”
第一個數(shù)字會在0~3范圍內(nèi)變化(0000 ~ 0011),移動鼠標時回復(fù)發(fā)生變化
第一個數(shù)字會在8~f范圍內(nèi)變化(1000 ~ 1111),點擊鼠標時會發(fā)生變化
第二個字節(jié):”00”,與鼠標左右移動相關(guān)
第三個字節(jié):“02”,與鼠標上下移動相關(guān)
工作總結(jié):對從鼠標獲取的數(shù)據(jù)進行了初步的處理,并以3個字節(jié)為一組。三個字節(jié)各自的含義如上表所示
2、 內(nèi)容2: 稍事整理
重點總結(jié):整理代碼,創(chuàng)建一個結(jié)構(gòu)體保存解讀鼠標所需要的變量,并將數(shù)據(jù)讀取處理過程封裝為一個函數(shù)
(1)bootpack.c
1、 內(nèi)容說明
將鼠標數(shù)據(jù)處理函數(shù)封裝為mouse_decode函數(shù),如下:
當(dāng)成功處理了鼠標傳來的數(shù)據(jù),將3個字節(jié)湊齊后,執(zhí)行return1在主函數(shù)中將鼠標星系顯示出來
3、內(nèi)容3: 鼠標解讀(2)
重點總結(jié):在結(jié)構(gòu)體中增加幾個變量存放解讀結(jié)果,并通過增加數(shù)據(jù)處理內(nèi)容獲得更加精細的數(shù)據(jù)內(nèi)容
(1) bootpack.c:MOUSE_DEC結(jié)構(gòu)體
1、內(nèi)容說明
新增加了3個變量x, y, btn。分別表示位置信息(后2個字節(jié))與鼠標按鍵狀態(tài)(第1個字節(jié))
(2) bootpack.c:mouse_decode函數(shù)
首先在phase == 1情況下增加如下語句,做數(shù)據(jù)檢查
1、 內(nèi)容說明
Dat的前半個字節(jié)范圍為(0000 ~ 0011),即前兩位始終為0. 后半個字節(jié)范圍為(1000 ~1111),第一位始終為1. 因此可以與0xc8(1100 1000)做與運算,當(dāng)dat正常輸入時,與運算的結(jié)果為0x08。否則這一字節(jié)數(shù)據(jù)不在范圍內(nèi),應(yīng)當(dāng)舍去。
下面是解讀處理的核心,將會獲得鼠標按鍵與位移的狀態(tài)
1、內(nèi)容說明
① 鼠標狀態(tài)”btn”:
鼠標狀態(tài)放在第一個字節(jié)buf[0]的低三位(按鍵狀態(tài))
②③ 鼠標移動狀態(tài)”x, y”:
鼠標水平、豎直移動信息x, y保存在第二位和第三位。另外還需要第一個字節(jié)中顯示位移的信息(前半個字節(jié)0~3)來正確表示移動信息。將x和y第8位及第8位以后(0x <-00)全部設(shè)為一(當(dāng)?shù)谝晃灰苿有畔?-3時)或全設(shè)為0
④ 對y符號進行取反操作
下面修改顯示部分
1、內(nèi)容說明
Btn為三位按鍵信息,當(dāng)btn=001時,表示按下右鍵。當(dāng)btn=010時,表示按下左鍵。當(dāng)btn=100時,表示按下中間滑輪
(2)結(jié)果展示
4、 內(nèi)容4: 移動鼠標指針
重點總結(jié):已完成鼠標解讀工作,現(xiàn)在讓鼠標指針動起來
(1)bootpack.c
Mdec.x, mdec.y表示鼠標向橫向、縱向移動的大小。可以用此實現(xiàn)鼠標移動
1、 內(nèi)容說明:坐標與鼠標位置更新
坐標與鼠標位置更新分為三個步驟
Step1:覆蓋原有鼠標圖案
Step2:計算移動后鼠標位置坐標mx, my。并對鼠標移動進行限制,鼠標不能移動超出屏幕。因此 0<(mx+x)<scrnx-16, 0<(my+y)<scrny-16。超出界限時,讓鼠標到達極限位置
Step3:覆蓋原有坐標并產(chǎn)生新坐標與新鼠標圖案
(2)結(jié)果展示
成功實現(xiàn)鼠標移動,但是沒有考慮疊加處理!
5、 內(nèi)容5: 通往32位模式之路
重點總結(jié):說明asmhead.nas中大約100行的代碼
第一部分:PIC關(guān)閉一切中斷
第二部分:允許訪問1MB以上的內(nèi)存空間
第三部分:切換到保護模式
第四部分:bootpack的傳遞
第五部分:bootpack的啟動
第六部分:waitkbdout函數(shù)
第七部分:memcpy函數(shù)
(1) PIC關(guān)閉一切中斷
1、 內(nèi)容說明
因為在CPU進行模式轉(zhuǎn)換與PIC進行初始化時,不允許中斷發(fā)生。所以要把中斷全部屏蔽掉。其中NOP使CPU簡單休息,避免連續(xù)的OUT操作。C語言表示如下:
(2) 允許訪問1MB以上的內(nèi)存空間
1、內(nèi)容說明
Waitkbdout功能是往鍵盤控制電路發(fā)送指令。此處是使鍵盤控制電路的附屬端口輸出0xdf從而讓A20GATE信號線變成ON的狀態(tài)。A20GATE信號線能使內(nèi)存1MB以上的部分變成可使用狀態(tài)。
(3) 切換到保護模式
1、內(nèi)容說明
① INSTRSET指令:為了使用386以后的LGDT, EAX, CR0指令
② 進入保護模式:將CR0的最高位設(shè)為0,第一位設(shè)為1即可進行模式切換,進入保護模式
③ JMP pipelineflush:
切換到保護模式后,機器語言的解釋發(fā)生了變化。因為CPU為了加快執(zhí)行速度使用了管道,提前解釋后面的語言。因此模式改變后需要重新解釋
同時切換到保護模式后,除了CS以外的所有段寄存器都從0x0000變成了0x0008
(4)bootpack的傳遞
1、 內(nèi)容說明
1.在asmhead結(jié)束的地方,緊連著bootpack最前面部分
將bootpack.hrb開始的512KB內(nèi)容復(fù)制到BOTPAK(0x00280000號)地址處理
2.將啟動扇區(qū)復(fù)制到1MB以后的內(nèi)存從0x7c00復(fù)制512個字節(jié)到DSKCAC(0x00100000)處理
3.將出去啟動區(qū)的部分復(fù)制到1MB以后的內(nèi)存
從DSKCAC0+512(0號扇區(qū)后512MB即第一號扇區(qū)開始的地址)復(fù)制減取啟動區(qū)512MB部分個字節(jié)到DSKCAC+512處理(前512被啟動區(qū)占用)
(5) bootpack的啟動
1、內(nèi)容說明
對bootpack.hrb的headre進行解析,將執(zhí)行所必須的數(shù)據(jù)傳送過去。即將bootpack.hrb第0x10c8字節(jié)開始的0x11a8字節(jié)復(fù)制到0x00310000號地址去。
① 設(shè)置轉(zhuǎn)移數(shù)據(jù)的大小:
數(shù)據(jù)的大小是以雙字為單位的,因此鼠標傳來的數(shù)據(jù)大小為傳來字數(shù)/4。但從鼠標傳來的數(shù)據(jù)以3個字節(jié)為一組,如果直接除以4,超出4的部分(字節(jié)數(shù)除以4的余數(shù))會被忽略。因此在計算前使字節(jié)數(shù)+3.
但是當(dāng)ECX為0,即沒有需要傳送的數(shù)據(jù)時,會跳轉(zhuǎn)到Skip
② 設(shè)置轉(zhuǎn)送源地址:
[EBX + 20]是bootpack.hrb之后的20號地址,值為0x10c8
③ 設(shè)置轉(zhuǎn)送目的地址
[EBX + 12]是bootpack.hrb之后的12號地址,值位0x00310000
同時介紹了“紙娃娃系統(tǒng)”的內(nèi)存分布圖
(6) waitkbdout
1、內(nèi)容說明
Waitkbdout功能是往鍵盤控制電路發(fā)送指令,與wait_KBC_sendready相同,也添加了指令,從0x60號設(shè)備進行IN的處理,如果控制器有鍵盤代碼或者已經(jīng)累積了鼠標數(shù)據(jù),就把他們讀出來。當(dāng)數(shù)據(jù)不為空時,繼續(xù)跳轉(zhuǎn)到waitkbdout讀取數(shù)據(jù)
(7)memcpy
1、內(nèi)容說明
其中源地址、目的地址、數(shù)據(jù)大小分別保存在ECX, ESI, EDI三個寄存器中
(8)GDT0與GDTR
1、內(nèi)容說明
① ALIGNB指令:一直添加DBO,直到時機合適為止
② GDT0
GDT0是一種特定的GDT,0號是空區(qū)域不能定義段。1,2號由下式設(shè)定:
在GDT0內(nèi)寫入了16位的段上限和32位的段起始地址
最初狀態(tài)時,GDT在asmhead.nas里,并不在0x00270000 ~ 0x0027ffff范圍里。
因此應(yīng)盡快開放中斷,接收數(shù)據(jù)。因此需要在調(diào)色盤初始化和畫面準備之前重現(xiàn)創(chuàng)建GDT和IDT
二、遇到的問題及解決方法
填寫說明:分條目列出本次的實驗過程中遇到的問題和解決方法(可注明是哪位同學(xué)幫忙解決問題),描述問題時應(yīng)配上相關(guān)的截圖和標記,描述解決方法時應(yīng)先分析出現(xiàn)該問題的原因再講解決方法,盡量詳細。
1、 描述問題1:理解鼠標數(shù)據(jù)第一階段的if判斷操作
從鼠標傳來的數(shù)據(jù)以三個字節(jié)為一組進行解讀。其中第一個字節(jié)的前半個字節(jié)表示鼠標的移動情況,取值范圍為0~3 (0000 -> 0011)。后半個字節(jié)表示鼠標的按鍵狀態(tài),取值范圍為8~f (1000 -> 1111)。為了預(yù)防數(shù)據(jù)不在設(shè)定的范圍內(nèi),將輸入數(shù)據(jù)與0xc8做與運算。當(dāng)超出上述取值范圍后,獲得的值不為0x08,選擇舍去。
2、 描述問題2:理解ECX寄存器+3并向左移位的意義
數(shù)據(jù)的大小是以雙字為單位的,因此鼠標傳來的數(shù)據(jù)大小為傳來字節(jié)數(shù)/4。但從鼠標傳來的數(shù)據(jù)以3個字節(jié)為一組,如果直接除以4,超出4的部分(字節(jié)數(shù)除以4的余數(shù))會被忽略。因此在計算前使字節(jié)數(shù)+3.
三、程序設(shè)計創(chuàng)新點
填寫說明:分條目列出本次實驗過程中對教材的哪些部分進行了創(chuàng)新或者修改,寫清楚為什么要這樣做,這么做會得到怎樣的結(jié)果等,附上關(guān)鍵代碼和截圖。這部分是重點,占實驗日志總分的20%。
1、 描述創(chuàng)新點1,解決疊加處理問題
(1) 問題描述
在上述實現(xiàn)鼠標移動時,會發(fā)生疊加處理問題。即在覆蓋原有鼠標位置時,會同時覆蓋其他背景顏色不同的結(jié)構(gòu)。
(2) 可能原因分析
分析覆蓋算法,是通過矩陣覆蓋為背景色實現(xiàn)覆蓋。但是因為下面對話框不是背景顏色,因此會發(fā)生顏色疊加。
1.那我們是不是可以嘗試每次移動鼠標后都將畫面重新初始化
但是會出現(xiàn)如下結(jié)果:即鼠標圖像本身的影響
2.分析鼠標圖像以及顏色構(gòu)成,在代碼中將鼠標空余空余部分顯示為了背景顏色。因此可以通過把空余部分設(shè)為透明色,實現(xiàn)疊加
成功實現(xiàn)我們預(yù)定的目標
2、 描述創(chuàng)新點2,改變實心圓的移動步長
四、實驗心得體會
填寫說明:寫本次實驗的心得體會,例如:學(xué)到了什么、思考了什么、有何建議、解決問題的過程是怎樣的等等(根據(jù)個人實驗情況填寫,內(nèi)容沒有硬性要求)。
1、鼠標數(shù)據(jù)處理
2、坐標與鼠標位置更新
坐標與鼠標位置更新分為三個步驟
Step1: 覆蓋原有鼠標圖案
Step2: 計算移動后鼠標位置坐標mx, my。并對鼠標移動進行限制,鼠標不能移動超出屏幕。因此 0<(mx+x)<scrnx-16, 0<(my+y)<scrny-16。超出界限時,讓鼠標到達極限位置
Step3: 覆蓋原有坐標并產(chǎn)生新坐標與新鼠標圖案
3、 “紙娃娃系統(tǒng)”的內(nèi)存分布圖
4、理解解讀鼠標數(shù)據(jù)第一階段的if判斷操作
從鼠標傳來的數(shù)據(jù)以三個字節(jié)為一組進行解讀。其中第一個字節(jié)的前半個字節(jié)表示鼠標的移動情況,取值范圍為0~3 (0000 -> 0011)。后半個字節(jié)表示鼠標的按鍵狀態(tài),取值范圍為8~f (1000 -> 1111)。為了預(yù)防數(shù)據(jù)不在設(shè)定的范圍內(nèi),將輸入數(shù)據(jù)與0xc8做與運算。當(dāng)超出上述取值范圍后,獲得的值不為0x08,選擇舍去。
總結(jié)
以上是生活随笔為你收集整理的30天自制操作系统——Day8实验报告的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android sqlite数据库操作通
- 下一篇: 纸娃娃系统(摘自百科)