arm指令一般編碼格式和一般語法格式

參考文章一:

arm指令一般編碼格式和一般語法格式

1、編碼格式:
這裏寫圖片描述
2、語法格式:
這裏寫圖片描述
3、解釋:
3.1、<>內的項是必須的,{}內的項是可選的
3.2、opcode:指令助記符;cond:執行條件;S:是否影響CPSR寄存器的值;Rd:目標寄存器;Rn:第1個操作數的寄存器;operand2:第2個操作數;
3.3、大多數時候可以根據CPSR的條件標誌位覺得是否該執行指令。當條件滿足時才執行,否則不執行。
3.4、arm指令的16個條件碼,如下:
這裏寫圖片描述
3.5、示例代碼說明使用條件碼以實現高效的邏輯操作:

C代碼:
if(a> b)
    a++;
else
    b++;
對應的彙編代碼:
CMP R0,R1        ;R0(a)與R1(b)比較
ADDHI R0,R0,#1   ;若R0>R1,則R0=R0+1
ADDLS R1,R1,#1   ;若R0≤1,則R1=R1+1
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

arm指令尋址方式

1、尋址方式是根據指令中給出的地址碼字段來實現尋找真實操作數地址的方式。
2、數據處理指令的操作數尋址方式歸納如下:
指令格式:
這裏寫圖片描述

2.1、立即數方式,必須遵循規則:每一個立即數由一個8位的常數循環右移偶數位得到。公式表達爲:立即數 =8位常數循環右移2*4位二進制數 即immediate=const_8 ROR 2*bin_4。
比如,0x104爲合法的立即數,而0x101 不是合法的立即數。是不允許在指令中使用的。
2.2、寄存器方式,操作數即爲寄存器裏的數值
2.3、寄存器移位方式,操作數是寄存器裏的數值移位而得到,有如下移位操作:ASR,LSR,LSL,ROR,RRX等。

3、字及無符號字節的load/store指令尋址方式
3.1、load指令從內存讀取數據放入寄存器,store指令用於將寄存器中的數據保存到內存。
3.2、以LDR指令爲例說明:
LDR指令的編碼格式如下:
這裏寫圖片描述

LDR指令的語法格式如下:
這裏寫圖片描述

註釋:cond是指令執行的條件碼,Rd是目的寄存器的編碼,Rn和Address_mode一起構成了第二個操作數的內存地址。

3.3、尋址方式由基址寄存器Rn和地址偏移量address_mode兩部分組成,其中地址偏移量有三種格式:立即數,寄存器,寄存器及一個移位常數。
3.4、尋址方式的地址計算方法有三種:偏移量方法,事先更新方法(即在指令的內存訪問完成後進行基址寄存器內容更新的方式),事後更新方法(在指令的內存訪問完成計算新地址的方式)。
3.5、根據尋址方式的地址計算方法和地址偏移量可知第二個操作數的內存地址共有如下9種格式:
這裏寫圖片描述
以第一種格式爲例說明第二個操作數的內存地址的計算方法:
[, #+/- ]表示基址寄存器Rn值加或減偏移量,它的指令編碼爲:
這裏寫圖片描述

使用偏移量方法計算內存地址,它的僞代碼表示爲:

if U == 1 then
    address = Rn + offset_12
else /*U = 0*/
    address = Rn - offset_12    
  • 1
  • 2
  • 3
  • 4

4、雜類Load/Store指令的尋址方式
4.1、指令的語法格式如下:
這裏寫圖片描述

4.2、指令中內存單元的尋址方式有以下6種:
這裏寫圖片描述

4.2、以第三種尋址方式說明內存地址的計算方法
使用該尋址方式[, #+/-]! 的指令編碼格式如下:
這裏寫圖片描述
使用事先更新方法計算內存地址,它的僞代碼如下:

offset_8 = (immedH << 4) OR immedL
if U == 1 then
    address = Rn + offset_8
else /*U = 0*/
    address = Rn - offset_8
if ConditionPassed(cond) then
    Rn = address
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

5、批量Load/Store指令的尋址方式
5.1、指令功能是實現在一組寄存器和一塊連續的內存單元之間傳輸數據
5.2、它的語法格式和指令編碼格式如下:
這裏寫圖片描述
這裏寫圖片描述
P位表示基址寄存器Rn所指的內存單元是否包含在指令使用的內存塊中。
U位表示地址變化的方向
W位表示指令執行後,基址寄存器Rn的值是否更新
L位表示操作的類型
5.3、address_mode表示地址變化方式,有四種,如下所示:
這裏寫圖片描述

以(DA)事後遞減(U=0)方式 爲例說明內存地址的計算方法
DA指令編碼格式如下:
這裏寫圖片描述
內存地址的算法,僞代碼表示如下:

start_address = Rn-(Number_Of_Set_Bits_In(register_list)*4)+4
end_address =Rn
if ConditionPassed(cond) and W == 1 then
    Rn = Rn - (Number_Of_Set_Bits_In(register_list) * 4)
  • 1
  • 2
  • 3
  • 4

6、協處理器Load/Store指令的尋址方式
6.1、指令的功能是在arm處理器和協處理器之間傳輸批量數據
6.2、指令的語法格式和編碼格式如下:
這裏寫圖片描述
這裏寫圖片描述
對各個標誌位含義的解釋:
U位表示基址寄存器Rn的更新方式
N位一般表示傳輸數據的字節大小
W位表示指令執行後,基址寄存器Rn的值是否更新
L位表示操作的類型

文章原地址:http://blog.csdn.net/starshinning975/article/details/48580925

參考文章二:

指令基本格式:

     <opcode>{<cond>}{S} <Rd>,<Rn>{,<operand2>}

1、<>內的項是必須的,{}內的項是可選的,cond若不附指令後使用默認條件AL(無條件執行)。

2、opcode:指令助記符,如LDR,STR等;

3、cond:執行條件,如EQ,NE等;

4、S:是否影響CPSR寄存器的值;

5、Rd:目標寄存器;

6、Rn:第一個操作數的寄存器;

7、operand2:第二個操作數;ARM指令中,靈活使用第二個操作數可提高代碼效率,第二個操作數的形式有:

    #immed_8r   ——常數表達式;

    Rm                ——寄存器方式;

    Rmshift     ——寄存器移位方式;

其指令編碼格式如下:

31-28

27-25

24-21

20  

19-16

15-12

11-012位)

cond

001

opcode

S

Rn

Rd

shifter_operand

 

#immed_8r:

   該常數必須對應8位位圖(即首尾兩個"1"bit間的間距爲6bits且該常數通過循環左移偶數位所有bit=1的位必集中在低8bits)。如 0x1FE、511、0xFFFF、0x1010、0xF0000010爲非法常量,0x3FC、0、0xF0000000、200、 0xF0000001爲合法常量。

利用這種轉換巧妙的實現了:在32bits的ARM指令代碼中集成32bits的立即數(常數)。如立即尋址的 數據處理指令的指令代碼爲:xxxx001a aaaSnnnn ddddrrrr bbbbbbbb,則其第二個操作數op2=#b,ROR #2r,由op2到指令碼的轉換經編譯器完成。

 

對其中的operand2的常數表達式有這樣的規定:該常數必須對應8位位圖,即常熟是由一個8位的常熟循環右移偶數位得到的。這句話的意思是說,當用12位第二操作數來表示一個32位立即數時,採用的是將8位數通過移位的方式來實現的,其中12位第二操作數的低八位存放被移位的基本數(取值範圍爲0255),而高四位存放的是循環右移的位數,因爲位四位二進制數,所以取值範圍位爲015,而對應的移位位數則爲030位,也就是說若移位數爲0,則表示基本數不變,若移位數位1,則表示將基本數在32位數字空間中循環右移2位,若移位數位5,則表示將基本數在32位數字空間中循環右移10位,若移位數位10,則表示將基本數在32位數字空間中循環右移20位,依次類推。舉例表示:

     AND R1,R2,#0xff

     當處理器處理這條指令的第二操作數0xff時,因爲0xff爲8位二進制數,所以處理器就將其直接放進8位“基本”數中,而4位“移位”數則爲0.

     AND R1,R2,#0x104

     當處理器處理這條指令的第二操作數0x104時,因爲此時0x104已經超過了8位二進制數,所以處理器就要將其“改造”一下,我們先把0x104轉換成二進制0000 0000 0000 0000 0000 0001 0000 0100,我們可以看到,這個數是0000 0000 0000 0000 0000 0000 0100 0001通過循環右移30位得到的,因此改造後的結果是8位“基本”數中存放0100 0001,而“移位”數爲15。

     AND R1,R2,#0xff000000

     當處理器處理這條指令的第二操作數0xff000000時,處理器同樣要對其“改造”,我們先把0xff000000轉換成二進制1111 1111 0000 0000 0000 0000 0000 0000,我們可以看到,這個數是0000 0000 0000 0000 0000 0000 1111 1111通過循環右移8位得到的,因此改造後的結果是8位“基本”數中存放1111 1111,而“移位”數爲4。

      我想,通過以上的三個例子,就應該明白了8位位圖的原理了。但是,有些數並不符合8位位圖的原理,這樣的數在進行程序編譯時,系統將會提示出錯,下面再舉幾個違反8位位圖的例子:比如0x101,轉換成二進制後位0000 0000 0000 0000 0000 0001 0000 0001,像這個數,無論向右循環幾位,都無法將兩個1同時放到低8位中,因此不符合8位位圖;再比如0x102,轉換成二進制後位0000 0000 0000 0000 0000 0001 0000 0010,如果將兩個1同時放到低8位中,即轉換成二進制後爲0000 0000 0000 0000 0000 0000 1000 0001,需要將此二進制數向右移31位,這也不符合循環右移偶數位的條件,因此0x012也不符合8位位圖;再舉一個0xff1,轉換成二進制後將會有9個1,不可能將其同時放入8位中,因此當然也不符合啦。

      通過正反例的比較,可以總結如下:第一,判斷一個數是否符合8位位圖的原則,首先看這個數轉換成二進制後1的個數是否不超過8個,如果不超過8個,再看這n個1(n<=8)是否能同時放到8個二進制位中,如果可以放進去,再看這八個二進制位是否可以循環右移偶數位得到起初被判斷的那個數值,如果可以,則此數值即爲符合8位位圖原理,否則,不符合。第二,用12位的編碼來表示一個任意的32位數是不可能的,只能通過循環右移八位二進制數偶數位來得到一部分32位數,其餘的無法表示的32位數,只有通過其它途徑獲得了,比如0xffffff00,可以通過0x000000ff按位取反得到,因此在以後的編程中,一定要注意用到的第二操作數是否符合8位位圖。

 

 

Rm:

   在寄存器方式下,第二個操作數即寄存器的數值;

Rm,shift:

   在寄存器移位操作方式下,將寄存器的移位結果作爲操作數,但Rm的值保持不變,移位方法有下:

   其中n取值一般在1--31之間。

8、The ARM instruction set:

9、指令條件碼:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章