欧美极品高清xxxxhd,国产日产欧美最新,无码AV国产东京热AV无码,国产精品人与动性XXX,国产传媒亚洲综合一区二区,四库影院永久国产精品,毛片免费免费高清视频,福利所导航夜趣136

 找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 4333|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

從ARM匯編指令機(jī)器碼解釋一些問題

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
本帖最后由 51黑tt 于 2016-3-6 15:28 編輯

從ARM匯編指令機(jī)器碼解釋一些問題

為什么MOV R0, #0×12345678這條指令無(wú)法編譯,而MOV R0, #0x678卻可以編譯通過?
為什么芯片會(huì)有立即數(shù)尋址,寄存器尋址,間接尋址等多種尋址方式?一種尋址方式不可以么?
為什么B跳轉(zhuǎn)指令只能跳轉(zhuǎn)到±32MBytes的范圍內(nèi)?

下面,我們一起來(lái)看看ARM7的指令格式,從指令格式中找出這些問題的答案。

ARM7內(nèi)核采用的是RISC精簡(jiǎn)指令集,所有的ARM指令都是32bits的,在這32bits里既包含了指令的指令碼,也包含了指令需要運(yùn)算的數(shù)據(jù),以MOV指令為例,通過MOV指令的32bits可以識(shí)別出這是一個(gè)MOV指令,又可以在這32bits里找到源寄存器和目的寄存器。我們來(lái)看一下MOV指令的機(jī)器碼格式:
圖 6  MOV指令的機(jī)器碼格式
28~31bitscond)是條件碼,就是表明這條語(yǔ)句里是否有大于、等于、非零等的條件判斷,這4bits共有16種狀態(tài),分別為:
二進(jìn)制碼指令符號(hào)含義二進(jìn)制碼指令符號(hào)含義
0000EQ相等0001NE不等
0010CS/HS進(jìn)位/無(wú)符號(hào)數(shù)大于等于0011CC/LO清進(jìn)位/無(wú)符號(hào)數(shù)小于
0100MI/負(fù)數(shù)0101PL/正數(shù)或0
0110VS溢出0111VC沒溢出
1000HI無(wú)符號(hào)數(shù)大于1001LS無(wú)符號(hào)數(shù)小于等于
1010GE有符號(hào)數(shù)大于等于1011LT有符號(hào)數(shù)小于
1100GT有符號(hào)數(shù)大于1101LE有符號(hào)數(shù)小于等于
1110AL任何條件1111-未定義
表 1  匯編語(yǔ)言條件碼
指令與條件碼可以有多種組合,比如MOV指令可以有MOVMOVEQMOVLT等多種形式。前面我們說過狀態(tài)寄存器里有NZCV的狀態(tài)標(biāo)志,當(dāng)執(zhí)行一條指令時(shí),芯片就會(huì)將這條指令的條件碼與狀態(tài)寄存器中的狀態(tài)標(biāo)志做比較,如果狀態(tài)寄存器中的狀態(tài)標(biāo)志滿足這條指令的條件碼時(shí),則執(zhí)行這條語(yǔ)句,如果不滿足則不執(zhí)行這條指令。狀態(tài)寄存器中的狀態(tài)標(biāo)志是受某些指令影響的,因此在使用有條件碼的指令進(jìn)行判斷前,必然會(huì)有其它指令配合使用,先修改狀態(tài)寄存器中的狀態(tài)標(biāo)志,例如:
CMP    R1, #0
BEQ    GETNEXTTASKSP
第一條指令“CMP”是一個(gè)“比較”指令,如果R1等于0,那么它就將狀態(tài)寄存器中的Z置為1,表示結(jié)果為真,否則,將狀態(tài)寄存器中的Z置為0,表示結(jié)果為假。第二條指令其實(shí)是一條“B”指令,是“跳轉(zhuǎn)”指令,B之后的“EQ”就是條件碼,從表1中可以知道,條件是“相等”時(shí)才執(zhí)行。
當(dāng)R1等于0時(shí),CMP指令就將Z置為1,執(zhí)行BEQ時(shí)滿足條件,就執(zhí)行了跳轉(zhuǎn)。如果R1不等于0CMP指令就將Z置為0,執(zhí)行BEQ時(shí)不滿足條件,就不執(zhí)行跳轉(zhuǎn)。
同理,只有當(dāng)狀態(tài)寄存器中的標(biāo)志為相等時(shí),MOVEQ指令才會(huì)執(zhí)行,這時(shí)其功能與MOV指令相同。而MOVLT指令則是當(dāng)狀態(tài)寄存器中的標(biāo)志為有符號(hào)數(shù),并且處于小于狀態(tài)時(shí)才會(huì)執(zhí)行的MOV指令。MOV指令的條件碼是AL,因此MOV指令可以不管任何條件都去執(zhí)行。其它指令也可以與條件碼組合使用,具體情況請(qǐng)查閱參附錄中的參考文檔2
25bitI)是用來(lái)區(qū)別shifer_operand域是采用立即數(shù)尋址方式還是寄存器尋址方式,該bit0表示寄存器尋址方式,為1表示立即數(shù)尋址方式,這就涉及到了指令的尋址方式。
尋址方式的出現(xiàn)不是為了使指令能有多種寫法,而是受指令長(zhǎng)度限制被迫產(chǎn)生的產(chǎn)物。以MOV指令為例,如果采用立即數(shù)尋址,立即數(shù)的長(zhǎng)度不可能超過shifer_operand域的長(zhǎng)度(MOV指令可以采用移位的方式裝下部分更長(zhǎng)的立即數(shù),這些不在討論之內(nèi)),因此我們就不可能使用
MOV R0, #0×12345678
這條指令。立即數(shù)#0×1234567832bits數(shù)據(jù),已經(jīng)超過了shifer_operand域所能裝下的最長(zhǎng)12bits數(shù)據(jù),如果把0×12345678全部被存到指令中,那么該指令中將無(wú)法存儲(chǔ)條件碼等其它指令信息,因此,這條指令在編譯時(shí)就會(huì)報(bào)錯(cuò)。
為了解決這個(gè)問題,芯片設(shè)計(jì)人員就設(shè)計(jì)了寄存器尋址方式,在ARM7中每種模式有16個(gè)通用寄存器,24次方等于16,因此只需要用4bits就可以為每個(gè)寄存器分配一個(gè)編號(hào),R0~R15寄存器分別對(duì)應(yīng)0~15的編號(hào)。4bits的寄存器編號(hào)完全可以存入shifer_operand域。采用寄存器尋址時(shí),指令先查到寄存器的編號(hào),然后再?gòu)募拇嫫髦腥〕鍪褂玫臄?shù)據(jù),這樣就解決了MOV指令受指令長(zhǎng)度的限制而無(wú)法操作長(zhǎng)立即數(shù)的問題。
從上述描述的過程來(lái)看采用寄存器尋址方式必須先將數(shù)據(jù)放入一個(gè)寄存器中,然后才能使用MOV指令采用寄存器尋址。對(duì)比立即數(shù)尋址方式,它增加了指令的執(zhí)行時(shí)間,也增加了代碼,還多用了一個(gè)寄存器,但它的優(yōu)點(diǎn)是可以操作長(zhǎng)的數(shù)據(jù)。
除了上面這兩種尋址方式外,ARM7還有多種其它尋址方式,每種尋址方式都有其自身的特點(diǎn),適用不同的場(chǎng)景,這里不介紹了。
21~24bitsopcode)是指令碼,用來(lái)表明這條指令是什么指令,例如,MOV指令的指令碼是0b1101,看到0b1101,芯片就將這條指令當(dāng)做MOV指令來(lái)解析。
20bitS)就是指令中S標(biāo)志的體現(xiàn),該bits0表示指令不帶S,為1表示指令帶S,功能見上述指令介紹。
16~19bitsSBZ)手冊(cè)中沒查到是什么意思,SBZ應(yīng)該是should be zero的意思,對(duì)比了幾條指令發(fā)現(xiàn)該域果然全是0,應(yīng)該是保留位。
12~15bitsRd)是指令中的目的寄存器,存放寄存器的4bits編號(hào)。
0~11bitsshifter_operand),指令的操作數(shù)。

下面我找了4條指令,將MOV指令做一個(gè)對(duì)比:
指令
機(jī)器碼
指令格式
cond00IopcodeSSBZRdshifer_operand
MOV R1, #0×64E3A0106411100011101000000001000001100100
條件碼為1110適用任何條件 立即數(shù)方式MOV的指令碼指令沒有S標(biāo)志 目的寄存器為R1源操作數(shù)為立即數(shù)0×64
MOVS PC, R14E1B0F00E11100001101100001111000000001110
條件碼為1110適用任何條件 寄存器方式MOV的指令碼指令有S標(biāo)志 目的寄存器為R15源操作數(shù)為寄存器R14
MOVLT R3, #0×1B3A0300110110011101000000011000000000001
LT的條件碼為1011 立即數(shù)方式MOV的指令碼指令沒有S標(biāo)志 目的寄存器為R3源操作數(shù)為立即數(shù)1
MOVEQ R0, R101A0000100000001101000000000000000000001
EQ的條件碼為0000 寄存器方式MOV的指令碼指令沒有S標(biāo)志 目的寄存器為R0源操作數(shù)為寄存器R1
表 2  MOV指令匯編格式對(duì)比

BL指令跳轉(zhuǎn)到目的地址,同時(shí)將BL指令的下條指令地址存入LR寄存器供程序返回時(shí)使用,調(diào)用函數(shù)時(shí)可以使用BL指令,如:
0×00080398 EB0002E2  BL    0x00080F28
0×00080398BL指令所在的地址,EB0002E2BL指令的機(jī)器碼,0x00080F28BL指令要跳轉(zhuǎn)到的地址。從這個(gè)格式來(lái)看,BL指令好像是一個(gè)絕對(duì)跳轉(zhuǎn)指令,直接跳轉(zhuǎn)到0x00080F28這個(gè)地址,其實(shí)不然,BL指令是一個(gè)相對(duì)跳轉(zhuǎn)指令,格式如下:



BL指令的0~23bits存放的是要跳轉(zhuǎn)的相對(duì)地址,由于指令所在地址必須是4字節(jié)對(duì)齊的,因此跳轉(zhuǎn)的地址最低2bits必然是0,因此BL指令0~23bits保存的是省略這最低2bits的地址,如果補(bǔ)全了這2bitsBL指令就可以表示26bits的跳轉(zhuǎn)地址。在這26bits中需要使用1bit表示向前跳還是向后跳,那么剩下的25bits就可以表示32MByts的范圍了,225=32M,因此,我們?cè)诤芏辔臋n上可以看到B跳轉(zhuǎn)指令只能跳轉(zhuǎn)到±32MBytes范圍內(nèi)的說明,就是這個(gè)原因。
上面這個(gè)BL指令要跳轉(zhuǎn)的相對(duì)地址是0x2E2BL指令0~23bits),補(bǔ)充2個(gè)最低位后,跳轉(zhuǎn)的相對(duì)地址為0xB88,由于ARM72級(jí)流水線,所以跳轉(zhuǎn)到的指令需要多加8個(gè)字節(jié),BL要跳轉(zhuǎn)的實(shí)際地址為0×00080398+0xB88+8=0x00080F28
這條BL指令執(zhí)行下面的操作:
LR = 0x0008039C
PC = 0x00080F28
在操作系統(tǒng)中我們沒有使用BL指令,就是因?yàn)槲覀儾恢牢覀兯{(diào)用的函數(shù)是否會(huì)超出BL指令的跳轉(zhuǎn)范圍,但我們可以看到編譯器編譯出的很多程序都是使用BL指令調(diào)用函數(shù)的,編譯器之所以不怕跳轉(zhuǎn)超出±32MBytes的范圍,是因?yàn)榫幾g器在編譯時(shí)就知道了程序所需要跳轉(zhuǎn)的范圍,它會(huì)為±32MBytes之內(nèi)的跳轉(zhuǎn)分配BL指令,保證BL指令不會(huì)超出范圍。在這里以BL指令為例,介紹一下B指令的相關(guān)知識(shí)。



分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表