一看到題目寫著 匯編二字辣卒,是不是心里一瞬間就產(chǎn)生畏懼感了呢(笑)鼓蜒,其實(shí)匯編沒有想得那么可怕的,我第一次接觸匯編的時(shí)候因?yàn)椴坏梅ù茁玻彩歉械筋^昏腦漲党晋,被一堆寄存器搞得暈暈乎乎谭胚,現(xiàn)在回頭再看徐块,發(fā)現(xiàn)其實(shí)理清楚邏輯,它并沒有那么可怕灾而。
之所以在這里介紹幾個(gè)匯編指令是因?yàn)楹兀陂_發(fā)OS的過程中,如果一直用二進(jìn)制編碼去寫程序是一件讓人很難受的事情旁趟,而借助匯編昼激,可以極大的縮短代碼量,更好的理清思維锡搜。 在第一篇文章中我們用二進(jìn)制編輯器寫出了一個(gè)簡(jiǎn)單的開機(jī)引導(dǎo)橙困,在這一篇文章中我們用匯編語言對(duì)其進(jìn)行改寫,不要這么快就畏懼哦~相信看完本文耕餐,大家對(duì)匯編會(huì)有一個(gè)新的認(rèn)識(shí)凡傅, “哦,其實(shí)匯編并不是很可怕嘛~”
首先看一下改寫之后的代碼
匯編代碼表示
; 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
好吧肠缔,我承認(rèn)這一堆看起來很難受夏跷,那么我們把它改寫成C代碼,這樣開起來就會(huì)容易些
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;
這樣看起來好多了吧
不過好像那些奇怪的大寫字符還是很多明未,別急槽华,那些就是開頭提到的寄存器了,接下來詳細(xì)解釋一下這些寄存器的功能和語句的含義亚隅。
詳解匯編語句以及寄存器
DB指令:即data byte硼莽,它的含義是往文件中直接寫入1個(gè)字節(jié)的指令
RESB指令:即reserve byte,從當(dāng)前的地址開始空出N個(gè)字節(jié)庶溶, eg:RESB 10:從當(dāng)前地址空出10個(gè)字節(jié)
DW:data word煮纵,代表8位(2字節(jié))
DD:data doubleword,代表16位(4字節(jié))
IPL:initial program loader偏螺,啟動(dòng)程序加載器
MOV指令:很常用的指令行疏,功能非常簡(jiǎn)單,即賦值
eg: MOV AX, 0 ;即AX = 0; MOV SS, AX ;即SS = AX套像; 還是很好理解吧~
寄存器解釋
接下來就是重頭戲了酿联,也就是對(duì)幾個(gè)重要的寄存器進(jìn)行解釋
AX(accumulator):累加寄存器(進(jìn)行加法運(yùn)算)
CX(counter):計(jì)數(shù)寄存器
DX(data):數(shù)據(jù)寄存器
BX(base):基址寄存器,(大家在數(shù)據(jù)結(jié)構(gòu)應(yīng)該接觸過這個(gè)概念夺巩,就是地址的起始參照地址)
SP(stackpointer):棧指針寄存器
BP(basepointer):基址指針寄存器
SI(sourceindex):源變址寄存器
DI(destinationindex):目的變址寄存器 ps:上面所說的都是16位寄存器
下面的寄存器是8位寄存器贞让,很簡(jiǎn)單是將上述的AX,CX,DX,BX分為高八位低八位
AH,CH,DH,BH:他們是上述的寄存器的高八位(high)
AL,CL,DL,BL:他們是上述的寄存器的低八位(low)
有心的同學(xué)們?cè)谶@里也會(huì)會(huì)發(fā)問,
”既然有16位和8位寄存器柳譬,那么有沒有32位的寄存器呢喳张?” 當(dāng)然是有的,因?yàn)槲覀冇玫牟欢嗝腊模@里就不贅述了销部,感興趣的可以去google一下摸航,相信會(huì)有很多收獲。
那我們繼續(xù)舅桩,接下來說到的是段寄存器
ES(extra segment):附加段寄存器
CS(code segment):代碼段寄存器
SS(stack segment):棧段寄存器
DS(data segment):數(shù)據(jù)段寄存器 他們的功能從名稱上就可以反映出來
大家看下面這條語句
MOV AX [SI]
如果SI沒有加“[]”酱虎,大家都能猜到他的作用是將SI中的數(shù)據(jù)賦值給AX,但此處加了括號(hào)擂涛,它的意思就變成將 SI的地址存儲(chǔ)到AX中读串。 MOV指令有一個(gè)規(guī)則,即源數(shù)據(jù)和目的數(shù)據(jù)必須位數(shù)相同 所以上述語句就是講SI地址的 一個(gè)字節(jié)給予AX歼指。
ADD指令 顧名思義爹土,進(jìn)行加法運(yùn)算,比如: >ADD SI, 1 ; SI = SI + 10:從當(dāng)前地址空出10個(gè)字節(jié)
CMP指令 比較指令
JE指令 條件跳轉(zhuǎn)指令踩身,根據(jù)比較的結(jié)果決定跳轉(zhuǎn)與否胀茵。JE即 jump if equal 與CMP結(jié)合使用,當(dāng)比較的結(jié)果相等挟阻,則跳轉(zhuǎn)到指定的地址琼娘;若比較結(jié)果不同,則不跳轉(zhuǎn)附鸽,繼續(xù)執(zhí)行下一條指令脱拼。
看下面這段代碼
CMP AL, 0
JE fin
其實(shí)等價(jià)于
if(AL == 0)
{
goto fin;
}
INT指令 軟件中斷指令,(interrupt)坷备,INT后面是一個(gè)數(shù)字熄浓,使用不同的數(shù)字代表調(diào)用不同的函數(shù),這些函數(shù)都是寫在BIOS中的省撑,方便程序員調(diào)用赌蔑。
HLT指令 這條指令的目的是讓CPU停止動(dòng)作,但不是完全停止竟秫,那樣的話就得斷電娃惯。此處是指讓CPU進(jìn)入待機(jī)狀態(tài)。 玩過linux的同學(xué)應(yīng)該都用過“halt”這條指令進(jìn)行關(guān)機(jī)操作吧肥败。_
結(jié)語
這次介紹匯編還是比較吃力趾浅,畢竟自己明白一些和給別人講解還是不一樣的,不過大家放心啦馒稍,今后的開發(fā)會(huì)轉(zhuǎn)到C語言皿哨,看起來也不會(huì)很吃力,不過必要的時(shí)候還是要用匯編這張“王牌”纽谒,哈哈那么证膨,這次的文章就告一段落了,有些地方說的不對(duì)的佛舱,還請(qǐng)大家提出意見和建議椎例,現(xiàn)行謝過了