2015年9月3日 星期四

ARM指令碼解碼技巧 進階取巧篇

剛好有看到這篇 http://imrannazar.com/ARM-Opcode-Map ,雖然不知道確切的原理(應該跟邏輯層的設計方式有關係) , 但 arm 32bits指令只要靠bits 27~20與7~4就可判斷指令格式,thumb的則為bits 15~12與 11~8 .

以32bits來說共需12bits成判斷,thumb要靠8bits.

如果把判斷特徵位元可能的狀況列表出來,thumb至多不會超過256狀況,arm多了不少為 4096狀況,但因為某些位元已經固定住了,實際case會少上不少,不過若是人工手動撰寫,還是一件相當麻煩的事情.

因此以我個人來說,我的處理方式是借用程式,自己建立了兩個表單(arm跟thumb版),表單是把可能的格式列出(判斷特徵位元),列出幾個範例 (以arm 32bits為範例)

ps由於這樣的表格無法表現出位元之間相互的依存關係,所以讓後面的行數規則建立出來的items覆蓋前面的分類,也就是說前面若建立出 xxx 是某格式的指令 , 後面又同樣出現了 xxx 是某另一格式的指令,會以後來的為主.

000*****0**1;Data Processing
000********0;Data Processing
001*********;Data Processing
00010*000000;MRS
00*10*10****;MSR
000000**1001;Multiply
00001***1001;Multiply Long
00010*001001;Single Data Swap
000100100001;Branch and Exchange
000**0**1011;Halfword Data Transfer : Register Offset
000**0**1101;Halfword Data Transfer : Register Offset
000**0**1111;Halfword Data Transfer : Register Offset
000**1**1011;Halfword Data Transfer : Immediate Offset
000**1**1101;Halfword Data Transfer : Immediate Offset
000**1**1111;Halfword Data Transfer : Immediate Offset
010*********;Single Data Transfer
011********0;Single Data Transfer
011********1;Undefined
100*********;Block Data Transfer
101*********;Branch
110*********;Coprocessor Data Transfer
1110*******0;Coprocessor Register Operation
1110*******1;Coprocessor Register Transfer
1111********;Software Interrupt

0.1代表必定的固定位元,*代表有0或1兩種可能,這一串 0 . 1 . * 由 bits 27~20 與 bits 7~4 所構成,程式自動去列出表單格式所有可能,生成switch裡面的 case 項目.

case ...:  case ..: case ...: ..............
{
}
break;

case...: case ...: case  ...: ............................
{
}
break;

.
.
.
.
.
.

因此抓到指令後只要把特定的位元抓出來串列,透過這程式自動匯出的switch來判斷,就自然而然能進行解碼,不需要再一堆if else 因為多重判斷而減低解碼效率了.

解碼僅需幾個流程,抓指令,把指令特定幾個位元抓出串連,switch串連的數值,解碼完成.
不過像是 Data Processing 的切分出格式後,後續還要進一步抓opcode來判斷要做啥記算.

以上給有興趣的人參考.

平平是RISC,為啥MIPS就沒這麼麻煩...


沒有留言:

張貼留言