開發OS二日目之必要匯編指令

2e2eb9389b504fc2e40ad6e0e4dde71191ef6df9.jpg

一看到題目寫著 匯編二字,是不是心里一瞬間就產生畏懼感了呢(笑),其實匯編沒有想得那么可怕的,我第一次接觸匯編的時候因為不得法,也是感到頭昏腦漲,被一堆寄存器搞得暈暈乎乎,現在回頭再看,發現其實理清楚邏輯,它并沒有那么可怕。

之所以在這里介紹幾個匯編指令是因為,在開發OS的過程中,如果一直用二進制編碼去寫程序是一件讓人很難受的事情,而借助匯編,可以極大的縮短代碼量,更好的理清思維。 在第一篇文章中我們用二進制編輯器寫出了一個簡單的開機引導,在這一篇文章中我們用匯編語言對其進行改寫,不要這么快就畏懼哦~相信看完本文,大家對匯編會有一個新的認識, “哦,其實匯編并不是很可怕嘛~”

首先看一下改寫之后的代碼

匯編代碼表示

; hello-os
; TAB=4

    ORG     0x7c00          
    JMP     entry
    DB      0x90
    DB      "HELLOIPL"      
    DW      512           
    DB      1            
    DW      1              
    DB      2               
    DW      224           
    DW      2880            
    DB      0xf0            
    DW      9                
    DW      18          
    DW      2             
    DD      0               
    DD      2880         
    DB      0,0,0x29      
    DD      0xffffffff     
    DB      "HELLO-OS   "   
    DB      "FAT12   "      
    RESB    18              

entry:
MOV AX,0
MOV SP,0x7c00
MOV DS,AX
MOV ES,AX
MOV SI,msg
putloop:
MOV AL,[SI]
ADD SI,1
CMP AL,0
JE fin
MOV AH,0x0e
MOV BX,15
INT 0x10
JMP putloop
fin:
HLT
JMP fin
msg:
DB 0x0a, 0x0a
DB "hello, world"
DB 0x0a
DB 0
RESB 0x7dfe-$
DB 0x55, 0xaa
DB 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
RESB 4600
DB 0xf0, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00
RESB 1469432
好吧,我承認這一堆看起來很難受,那么我們把它改寫成C代碼,這樣開起來就會容易些

C代碼表示

entry:
AX = 0;
SS = AX;
SP = 0X7C00;
DS = AX;
ES = AX;
SI = msg;
putloop:
AL = BYTE[SI];
SI = SI + 1;
if(AL == 0)
{
goto fin;
}
AH = 0X0E;
BX = 15;
INT 0X10;
goto putloop;
fin:
HLT;
goto fin;
這樣看起來好多了吧

不過好像那些奇怪的大寫字符還是很多,別急,那些就是開頭提到的寄存器了,接下來詳細解釋一下這些寄存器的功能和語句的含義。

詳解匯編語句以及寄存器

DB指令:即data byte,它的含義是往文件中直接寫入1個字節的指令
RESB指令:即reserve byte,從當前的地址開始空出N個字節, eg:RESB 10:從當前地址空出10個字節
DW:data word,代表8位(2字節)
DD:data doubleword,代表16位(4字節)
IPL:initial program loader,啟動程序加載器

MOV指令:很常用的指令,功能非常簡單,即賦值
eg: MOV AX, 0 ;即AX = 0; MOV SS, AX ;即SS = AX; 還是很好理解吧~

寄存器解釋

接下來就是重頭戲了,也就是對幾個重要的寄存器進行解釋

AX(accumulator):累加寄存器(進行加法運算)
CX(counter):計數寄存器
DX(data):數據寄存器
BX(base):基址寄存器,(大家在數據結構應該接觸過這個概念,就是地址的起始參照地址)
SP(stackpointer):棧指針寄存器
BP(basepointer):基址指針寄存器
SI(sourceindex):源變址寄存器
DI(destinationindex):目的變址寄存器 ps:上面所說的都是16位寄存器
下面的寄存器是8位寄存器,很簡單是將上述的AX,CX,DX,BX分為高八位低八位

AH,CH,DH,BH:他們是上述的寄存器的高八位(high)
AL,CL,DL,BL:他們是上述的寄存器的低八位(low)
有心的同學們在這里也會會發問,

”既然有16位和8位寄存器,那么有沒有32位的寄存器呢?” 當然是有的,因為我們用的不多,這里就不贅述了,感興趣的可以去google一下,相信會有很多收獲。

那我們繼續,接下來說到的是段寄存器

ES(extra segment):附加段寄存器
CS(code segment):代碼段寄存器
SS(stack segment):棧段寄存器
DS(data segment):數據段寄存器 他們的功能從名稱上就可以反映出來
大家看下面這條語句

MOV AX [SI]
如果SI沒有加“[]”,大家都能猜到他的作用是將SI中的數據賦值給AX,但此處加了括號,它的意思就變成將 SI的地址存儲到AX中。 MOV指令有一個規則,即源數據和目的數據必須位數相同 所以上述語句就是講SI地址的 一個字節給予AX。

ADD指令 顧名思義,進行加法運算,比如: >ADD SI, 1 ; SI = SI + 10:從當前地址空出10個字節
CMP指令 比較指令
JE指令 條件跳轉指令,根據比較的結果決定跳轉與否。JE即 jump if equal 與CMP結合使用,當比較的結果相等,則跳轉到指定的地址;若比較結果不同,則不跳轉,繼續執行下一條指令。
看下面這段代碼

CMP AL, 0
JE fin
其實等價于

if(AL == 0)
{
goto fin;
}
INT指令 軟件中斷指令,(interrupt),INT后面是一個數字,使用不同的數字代表調用不同的函數,這些函數都是寫在BIOS中的,方便程序員調用。

HLT指令 這條指令的目的是讓CPU停止動作,但不是完全停止,那樣的話就得斷電。此處是指讓CPU進入待機狀態。 玩過linux的同學應該都用過“halt”這條指令進行關機操作吧。_

結語

這次介紹匯編還是比較吃力,畢竟自己明白一些和給別人講解還是不一樣的,不過大家放心啦,今后的開發會轉到C語言,看起來也不會很吃力,不過必要的時候還是要用匯編這張“王牌”,哈哈那么,這次的文章就告一段落了,有些地方說的不對的,還請大家提出意見和建議,現行謝過了

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 8086匯編 本筆記是筆者觀看小甲魚老師(魚C論壇)《零基礎入門學習匯編語言》系列視頻的筆記,在此感謝他和像他一樣...
    Gibbs基閱讀 37,388評論 8 114
  • 計算機通過執行指令序列來使機器得以工作,所以對于每一系列的計算機都有指定的一組指令集供計算機使用,這組指令...
    未來科技工作室閱讀 8,144評論 1 10
  • 王爽匯編全書知識點大綱 第一章 基礎知識 機器語言 匯編語言的產生 匯編語言的組成 存儲器 cpu對存儲器的讀寫 ...
    2c3ba901516f閱讀 2,453評論 0 1
  • 這個程序的核心目的是:試驗大地址的讀寫,在保護模式下面尋址空間可達4GB,實模式下只能尋址1MB。(why:為什么...
    王偵閱讀 851評論 0 0
  • 今天受邀去一位朋友那里喝茶看琥珀,覺察到自己好像無意識中會有些焦慮。從接到邀請開始,我的思緒就開始漂~她邀請我是不...
    596dea33d35b閱讀 269評論 0 0