ARM彙編之合法立即數的快速判斷方法

2020-12-02 電子產品世界
ARM彙編的數據處理指令中經常會使用到常數,而ARM彙編中規定使用的常數必須是立即數。

在討論什麼是立即數,為什麼有立即數,如何快速判斷立即數之前,我們先來弄明白一個問題:什麼不是立即數。

本文引用地址:http://www.eepw.com.cn/article/201611/317885.htm

彙編指令是對數據(指令、數據)對象的操作,很關鍵的一個問題我們如何尋找我們的操作對象?彙編指令是一門關於尋址的藝術。ARM有九種尋址方式:1.寄存器尋址2.立即尋址3.寄存器移位尋址4.寄存器間接尋址5.基址尋址6.多寄存器尋址7.堆棧尋址8.塊拷貝尋址9.相對尋址。 九中尋址方式都是再告訴我們如何尋找我們的操作對象,其中立即數尋址相對於其他尋址方式有什麼不同?

為了理解ARM指令是如何實現對數據對象操作,我們需要知道ARM指令的機器碼格式。(熟悉的可以直接跳到如何快速判斷合法立即數)(ARM指令的典型編碼格式如下:)


ARM指令語法格式如下:

opcode{}{s}rd,rn,

各個部分解釋如下:

*cond(bit[31:28]):指令的條件碼助記符,默認是al(無條件執行)

*type(bit[27:32]):指令碼類型,根據其編碼的不同,所代表的類型:00:數據處理指令及雜類Load/Store指令;01:Load/Store指令;10:批量Load/Store指令及分支指令;11:協處理指令與軟中斷指令

*X(bit[25]):第二操作數類型標誌碼。(X=0表示第二操作數是移位寄存器,X=1表示第二操作數是立即數)

*opcode(bit[24:21]):指令助記符,如mov

*S(bit[20]):指令的執行是否影響CPSR(當前程序狀態寄存器)的值(S:state)

*Rn(bit[19:16]):包含第一個操作數的寄存器編碼(RegisterNum)

*Rd(bit[15:12]):目標寄存器編碼(RegisterDestination)

*opcode2(bit[11:0]):第二操作數

ARM指令的第二操作數用法比較靈活,有如下幾種情況。

* 立即數

* 寄存器

* 寄存器移位

ARM指令裡有兩個操作數Rn,opcode2和一個目的寄存器Rd(用於存放操作結果),Rn為包含第一個操作數的寄存器地址,opcode2有三種形式:立即數方式、寄存器方式、寄存器移位方式,其中寄存器和寄存器位移方式也都是存儲的寄存器地址所以要通過寄存器間接獲得數據對象,也就是非立即,而立即數形式不同,指令中opcode2數據域不是地址而是數據本身,所以叫立即數。也就是說其它尋值方式最終操作的數據對象是放在Rn或opcode2所指向的寄存器地址中的數據,顯然立即數操作對象也需要根據地址尋找,但它所在的地址比較特殊,或者說它存儲的位置比較特殊,因為它直接存儲在指令opcode2中。

而opcode2隻有12位,也就是說opcode2所表示的立即數有一定限制0-4095,為了進一步擴大12bit數據所能表示數的範圍,ARM規定了數據的格式:也即

立即數是由一個8位的常數循環右移偶數位得到的,其中循環右移 的位數由一個4位2進位的兩倍表示,公式如下:

immediate=immed_8<

為什麼會有立即數這樣的規定呢?這是由於所有的ARM指令是精簡指令集,指令長度固定都是32位,對於ARM數據處理指令自然也是一樣。數據處理指令大致可包含3類,數據傳送指令、數據算術邏輯運算指令和數據比較指令。在一條ARM數據處理指令中,除了要包含處理的數據值外,還要標識ARM命令名稱,控制位,寄存器等其他信息。這樣在一條ARM數據處理指令中,能用於表示要處理的數據值的位數只能小於32位。

ARM在指令格式中設定,只能用指令機器碼32位中的低12位來表示要操作的常數。ARM處理器是按32位來處理數據的,ARM處理器處理的數據是32位,如果簡單的用這12位來表示,顯然範圍太小了,為了擴展到32位,因此使用了構造的方法,在12位中用8位表示基本數據值,用4位表示位移值,通過用8位基本數據值往右循環移動4位位移值*2次,來表示要操作的常數。這裡要強調最終的循環次數是4位位移值乘以2得到的,所以得到的最終循環次數肯定是一個偶數,為什麼要乘以2呢,實質還是因為範圍不夠,4位表示位移次數,最大才15次,加上8位數據還是不夠32位,這樣只能通過ALU的內部結構設計將4位位移次數乘以2,這樣就能用12位表示32位常數了。

通過循環偶數位得的到操作數,擴大了操作數的範圍,但也帶來了問題,並不是每個數據都能通過8位基本數據循環移動偶數為得到,如果你在ARM數據處理指令中使用的操作數,不是立即數,比如MOV R1,#0x12345678,編譯器就會報錯,所以我們在使用前必須進行判斷,這也是很多ARM相關求職筆試中常考的一道題目。

那怎樣怎麼快速判斷一個數是否是立即數?對於簡單的數字我們可以直接判斷,比如小於255的數字肯定是立即數。對相對複雜的數字進行判斷就需要先把它轉換為2進位形式,然後根據定義進行判斷了。我這裡總結了個比較快速的方法:(簡而言之,就是利用立即數的生成方法,迅速逆推到合法的8位常熟)

1、把數據轉換成二進位形式,從低位到高位寫成4位1組的形式,最高位一組不夠四位的,在最高位前面補0。

2、數1的個數,如果大於8個肯定不是立即數,如果小於等於8進行下面步驟。

3、如果數據中間有連續的大於等於24個0,循環左移4的倍數,使高位全為0。

4、找到最高位的1,去掉前面最大偶數個0。

5、找到最低位的1,去掉後面最大偶數個0。

6、數剩下的位數,如果小於等於8位,那麼這個數就是立即數,反之就不是立即數。

針對可能現的情況,舉5個典型例子:

(1)0x4FF (2)0x122 (3)0x234 (4)0xF000000F (5)0x8000007F

例1: 0x4FF

第一步:0100 1111 1111

第二步:其中1的個數是9個,大於8個,判定不是立即數

例2: 0x122

第一步: 0001 0010 0010

第二步: 其中1的個數4個,小於8,繼續

第三步: 其中沒有連續大於等於24個0,繼續

第四部: xx01 0010 0010 (最高位前面有3個0,最大偶數2,去掉2個0)

第五步: xx10 0011 0010 (最低位後面只有1個0,最大偶數0)

第六部: 剩下10 0011 0010 共10位,大於8,判定0x122不是立即數

例3: 0x234

第一步: 0010 0011 0100

第二步: 其中1的個數4個,小於8,繼續

第三步: 其中沒有連續大於等於24個0,繼續

第四部: xx10 0011 0100

第五步: xx10 0011 01xx

第六部: 剩下10 0011 01 共8位,等於8,判定0x234是立即數

例4: 0xF000000F

第一步: 1111 0000 0000 0000 0000 0000 0000 1111

第二步: 其中1的個數8個,沒有大於8,繼續

第三步: 其中有連續24個0,循環左移4位,使高位全為0

0000 0000 0000 0000 0000 0000 0000 1111 1111

第四部: xxxx xxxx xxxx xxxx xxxx xxxx xxxx 1111 1111

第五步: xxxx xxxx xxxx xxxx xxxx xxxx xxxx 1111 1111

第六部: 剩下1111 1111共8位,等於8,判定0xF000000F是立即數

例5: 0x8000007F

第一步: 1000 0000 0000 0000 0000 0000 0111 1111

第二步: 其中1的個數8個,沒有大於8,繼續

第三步: 其中有連續24個0,循環左移4位,使高位全為0

0000 0000 0000 0000 0000 0000 0111 1111 1000

第四部: xxxx xxxx xxxx xxxx xxxx xxxx 0111 1111 10xx

第五步: xxxx xxxx xxxx xxxx xxxx xxxx 0111 1111 10xx

第六部: 剩下0111 1111 10共10位,等於8,判定0x7000008F是立即數

問題還沒有結束,我們在ARM彙編中如何規避立即數這個問題呢,其實可以使用ARM彙編LDR偽指令,例如直接把MOV指令變為, LDR R1,=0x12345678這樣編譯器就不會報錯了。但這種方法也有弊端會增加開銷和影響執行效率。同時ARM彙編中還有有效數的概念,比如 MOV R1,#0xFFFFFFFF 指令中 0xFFFFFFFF 不是立即數,但是是有效數,編譯器最自動把原指令變換為 MVN R1,#0,也不會報錯。有效數判定:原數是立即數或者原數反碼是立即數。

希望對大家有幫助。


相關焦點

  • ARM彙編偽指令 宏的用法詳解
    當程序被彙編時,彙編程序將對每個調用進行展開,用宏定義取代源程序中的宏指令。但在使用子程序結構時需要保護現場,從而增加了系統的開銷,因此,在代碼較短且需要傳遞的參數較多時,可以使用宏彙編技術。包含在 MACRO 和 MEND 之間的代碼段稱為宏定義體,在MACRO偽操作之後的一行聲明宏的原型(包含宏名、所需的參數),然後就可以在彙編程序中通過宏名來調用它。在源程序被彙編時,彙編器將宏調用展開,用宏定義體代替源程序中的宏定義的名稱,並用實際參數值代替宏定義時的形式參數。
  • F.A.S.T方法快速判斷你是否有中風風險
    因為中風對時間敏感,所以立即行動是很重要的。但是你怎麼知道什麼時候打120電話呢?美國中風協會開發了一種方便的、容易記住的首字母縮寫,代表了三種主要的中風症狀。這個縮寫詞是FAST,是一個強調緊急和快速行動重要性的詞。
  • 4種判斷鴿群來了天落鳥的方法,別再傻傻數數量了,這幾種最快速
    4種判斷鴿群來了天落鳥的方法,別再傻傻數數量了,這幾種最快速和一些人喜歡養狗養貓不同的是,有一些人天生就喜歡鳥類,他們覺得鳥是非常有意思的動物,有些人甚至會在家養很多,比如養鴿子,養過鴿子的人應該都知道,在訓練鴿子往家飛回的時候,經常會引來一些其他不知名的鳥類飛回家
  • 以s3c2440為例的arm晶片的啟動過程
    arm 嵌入式晶片的啟動過程對於嵌入式菜鳥來說其實是很複雜的,很多人都是一知半解,存在很多誤區。 本文將以s3c2440為例詳細講述 arm 晶片的啟動過程。s3c2440支持兩種啟動模式:NAND FLASH 啟動和非 NAND FLASH 啟動(一般是NOR FLASH 啟動,並且可以配置數據寬度),通過 OM1、OM0 兩個管腳來控制。
  • 彙編:將兩位十進位數轉化為十六進位數
    這個是一個把兩位十進位數轉化為十六進位數的的彙編語言程序 考試題目
  • 孩子感冒如何快速選擇感冒藥?對照症狀判斷寒熱
    家長可以對照風寒 / 風熱感冒的症狀快速判斷寒熱:風寒感冒:惡寒重、發熱輕、喜溫、不怎麼出汗、鼻塞、流清涕、咽喉癢、咳嗽稀白痰、伴有頭痛、全身關節疼痛、舌質淡、苔薄白的症狀。風熱感冒:惡寒輕、多發熱、喜涼、出汗、鼻塞、流黃涕、嘴唇紅、喉嚨紅腫疼痛、口乾喜飲、咳嗽黃稠痰、舌質較紅、薄黃苔。
  • 學習逆向工程(外掛)基礎:彙編指令總結
    正文:首先我們應該先了解逆向工程的一個應用:遊戲外掛,玩過遊戲的人都知道遊戲外掛這個東西,也都想嘗試著去自己做一個,但是不知道怎麼入門,學習方法以及路線不清楚,下面我先教大家怎樣入門逆向工程。逆向工程的過程也就是把軟體逆向分析成代碼的過程,代碼可以實彙編代碼也可能是原始碼。
  • ARM如何讀寫Flash
    絕對跳轉就是直接指定目的地址的跳轉,比如你直接給pc賦一個立即數值,就是絕對跳轉。你也可以用bx/blx Rm來實現絕對跳轉。我其實對arm指令不熟,你自己琢磨一下吧。我只是說明了一種容易出現的錯誤,希望對你有幫助。8.設置tlb表了麼?
  • 有沒有比合法捕殺更人道更快速地處理城市流浪狗泛濫問題的方法?
    有沒有比合法捕殺更人道、更快速地處理城市流浪狗泛濫問題的方法?有人就覺得,流浪狗問題多是人說的錯,流浪狗泛濫,其實是人的錯!問一下,哪只狗願意走?餓得餓得餓,任人去追打、宰殺,難道它還願意流浪?應該是人在管,一輛車撞人,是車的過錯嗎?
  • 小學數學,一個數能同時被多個數整除怎麼判斷
    之前我們介紹過一些常見的數的整除判斷,並用位值原理進行了簡單的推導。我們再做個全面的梳理,推導過程大家可以去查看之前的相關文章,這裡就不再重複了。當然這些數的整除特性與判斷,都是基於十進位,一旦脫離這個基礎,推導及判定均不成立。
  • 狗狗救命篇之:受傷後的快速處理方法
    下面是一些狗狗受傷後的快速處理知識。1. 狗狗出現外傷和出血(車禍、刮傷)如果是小創口,只有小面積的皮膚損傷和肌肉暴露,可以直接使用無菌水(生理鹽水、乳酸林格)衝洗。這些人的藥店都能買到。狗狗出現燒傷家長千萬不要自己判斷狗狗燒傷的輕重程度(除非只是燒到一點皮,沒有破),無論是大面積還是小面積燒傷都需要到醫院處理。
  • 2019中考英語:真題分類彙編---書面表達之看圖作文
    英語真題分類彙編:書面表達之看圖作文 看圖作文 (一)(2009廣州) 請根據圖示的內容,把故事情節補充完整,要求語句通順、全文意思連貫。 注意:1.第1格要求至少寫出兩個完整的句子; 2.第2、3、4、5格要求將句子補充完整,單詞數不限; 3.第6格要求將 You'd better…補充完整後,再至少寫出一個完整的句子。 It was Christmas Day. My friends came to my house. 1_____ How time flied!
  • 中考英語:中考英語真題分類彙編---書面表達之看圖作文
    2009年 英語真題分類彙編:書面表達之看圖作文 看圖作文 (一)(2009廣州) 請根據圖示的內容,把故事情節補充完整,要求語句通順、全文意思連貫。 注意:1.第1格要求至少寫出兩個完整的句子; 2.第2、3、4、5格要求將句子補充完整,單詞數不限; 3.第6格要求將 You'd better…補充完整後,再至少寫出一個完整的句子。 It was Christmas Day. My friends came to my house. 1_____ How time flied!
  • 小學數學,數的整除特性,3的倍數判斷公式是怎麼來的
    我們單看個位數還能判斷哪些數的倍數呢?可以判斷5的倍數,某個數字個位只有是0或5的兩種情況才是5的倍數。還可判斷10的倍數,個位是0的整數才是10的倍數。我們這種判斷其實都是基於十進位,如果是其他進位的話這個這個準則就失去了它的意義。
  • 《動物之森》新手攻略之裡程數和初始工具
    《動物之森》新手攻略之裡程數和初始工具 上一期為大家帶來了第一天的攻略,今天將為大家帶來如何快速收集裡程數與獲得初始工具的方法。
  • 有比合法捕殺更人道、更快速地處理城市流浪狗泛濫問題的方法?
    有沒有比合法捕殺更人道、更快速地處理城市流浪狗泛濫問題的方法?都市裡的確有狗不栓繩,跑上馬路,出了車禍,狗其實要負主要責任。我想在鄉下也一樣適用。與我們之前的做法不同,汽車壓死雞鴨鴨都車主的過錯,全部由車主自己承擔!
  • 支招快速消氣的三種方法
    下面小編就為大家介紹幾種快速消氣的方法。一、生氣時,先問問自己「此氣該不該生?「有人專門對生氣作過研究,結論令人吃驚,人們日常生活中所生的氣,大多是不該生的氣。以下不妨略舉數端:1、他人無意或在不得已的情況下「冒犯「了你。如在馬路上被撞,公共汽車上挨踩,飯店用餐時服務員失手弄髒了你的衣服等等……這些都屬於不該生的氣。
  • 快速判斷貓咪生病的前兆
    相信鏟屎官在養育自己心愛的貓咪的時候,會有這樣一個問題:貓咪不像是人類,生病之後是不會說、不會表現出來的,怎樣才能提前通過一些貓咪生活中的小細節,或者貓的一些表現判斷貓咪即將生病呢?今天我們就來聊一聊貓咪生病的幾種症狀你知道嗎?
  • 一個快速有效判斷茶杯犬健康情況的方法,你還不快記下來?
    對於茶杯犬的健康情況來講,有一種方式能夠很好的觀測到寵物的健康情況,尤其對於新手飼養茶杯犬,這個方式會特別的簡單,並且能夠從中快速的了解到茶杯犬的健康程度,那麼這個方法就是觀察茶杯犬的大小便情況,通過糞便來判斷,因為對於狗狗來說很多疾病都會影響到它們的大小便情況,那麼該如何判斷呢,
  • 快速判斷信鴿疾病的七孔檢查法
    快速判斷信鴿疾病的七孔檢查法來源: 《信鴿》 作者: 周源富觀察糞便,能夠發現一些鴿子的常見病和多發病。要做出更正確的診斷,就需檢查鴿子的「七孔」。所謂「七孔」,是指鴿子的七處天然氣孔。一、口腔檢查當你發現一羽鴿子拉出的糞便不正常,並有怕冷,毛松,蜷縮,不食不飲等反常現象時,你就要抓住它,掰開它的喙,檢查口腔和咽喉的顏色。