首先我們需要知道的是計算機中的指令分為特權指令和非特權指令。其中特權指令大多是和作業系統底層相關的操作,如果任何程式都可以使用特權指令,那麼個作業系統也就距離崩潰不久了。實驗指南中用了乙個銀行取錢的例子來幫助大家理解什麼作業系統中的等級制度。
這裡我話了乙個簡單的來說明如何訪問非特權指令和特權指令。
當乙個程式需要訪問非特權指令時可以直接訪問。
當乙個程式需要訪問特權指令時,需要產生中斷進行核心態,然後由作業系統呼叫特權指令。
首先我們需要根據操作指南介紹的定義has_cte巨集,定義了以後nanos-lite會在panic()前呼叫_yield()來觸發自陷操作。
此時我們先執行下,看下結果
可以看到0f指令沒有實現,檢視i386手冊,可以看到這個指令是lgdt/ lidt。接下來可以根據描述 load m into idtr來實現這個指令。
首先來分析lidt指令,lidt指令對作用是載入中斷描述符,操作是將源運算元中的數值載入到中斷描述符**暫存器 。
make_ehelper(lidt)
接下來分析raise_intr()函式,這個函式的作用是用來模擬中斷操作,也就是這段的描述:
依次將eflags, cs(**段暫存器), eip暫存器的值壓棧
從idtr中讀出idt的首位址
根據異常號在idt中進行索引, 找到乙個門描述符
將門描述符中的offset域組合成目標位址
跳轉到目標位址
這部分**就不貼出來了,大家按照描述實現即可,其中要注意的是判斷門操作符的標誌符來區分操作是否有效。
實現後進行make run,結果如下:
(這個部分我當時不知道是否正確,只能進一步繼續操作。)更新,這個部分操作錯誤了,忘記在exec.c中新增操作指令。
這個部分沒什麼特別難實現的,按照說明一步一步操作即可。
按步驟操作
首先需要注意的是pusha壓棧過程是:
棧頂edi
esiebp
espebx
edxecx
eax然後是壓入錯誤嗎和異常訊號的操作:
棧頂eflags
cseip
err!!!注意,上面那個部分很重要,很重要。用來做什麼的,仔細讀講義~
實現完成後觸發乙個未處理的1號事件。
這個地方我卡住的原因是因為不知道tf->riq**的含義,通過谷歌查詢到 :
yield 0x81
syscall 0x80(後面發現pa3.2中介紹了這個兩個**的含義)
然後按照要求實現各個命令即可啦~
中識別出自陷事件_event_yield, 然後輸出發現yield事件,並且最終出發了main()函式中的panic()函式。
做完以後,發現是hit bad trap at eip = 0x00100032,這個地方應該是還有問題。繼續排查。(哈哈,原來是實現了pa3.2才會出現hit good trap!!
git log截圖
httpclient3 1下的請求頭和params
才開始使用這個東東,最開始以為在httpmethod的params中set乙個key和value,在client execute的時候就自動轉化成請求的header的。經過debug發現不是這個樣子,只有agent和host 這2個在params中設定的變數才作為請求頭髮過去的。其實host是htt...
使用Activex實現自動列印 不使用PAZU
最開始使用pazu控制項來實現自動列印。安裝了smart printer來列印tif檔案。使用localhost是可以的。但是用ip訪問,就不能用。需要license。雖然是免費申請的。但是麻煩啊,而且我的伺服器是外網不能訪問的。心一狠,我就不信不用pazu做不出來。在頁面上新增 js functi...
Oracle 實現自增列
sql server中實現自增列只需要將字段定義為identity 1,1 而在oracle中自增列需要使用乙個序列 sequence 和觸發器來實現。1.建立sequence,首先需要有create sequence或者create any sequence許可權 1 create sequenc...