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