說到文字池,首先第一個問題:什么是文字池?文字池又叫literal pool,它的本質就是ARM匯編語言代碼節中的一塊用來存放常量數據而非可執行代碼的內存塊。
那為什么要使用文字池呢?當想要在一條指令中使用一個 4字節長度的常量數據(這個數據可能是內存地址,可能是數字常量)的時候,由于ARM指令集是定長的(ARM指令4字節或Thumb指令2字節),就無法把這個4字節的常量數據編碼在一條編譯后的指令中。此時,ARM編譯器(編譯C源程序)/匯編器(編譯匯編程序) 就會在代碼節中分配一塊內存,并把這個4字節的數據常量保存起來,之后,再使用一條指令把這個4 字節的數字常量加載到寄存器中參與運算。 在寫C程序中,文字池的分配是由編譯器在編譯時自行分配安排的,但是,在寫匯編程序時,開發者可以自己進行文字池的分配,當然如果沒有自己分配匯編器也會代勞。不管何種情況,這不影響我們來了解學習一下文字池的知識。
LDR Rd,=const 偽指令可在單個指令中構造任何 32 位數字常數。使用此偽指令可生成超出MOV和MVN指令范圍的常數。LDR 偽指令可為特定的常數生成最高效的單個指令:如果可以用單個MOV或MVN 指令構造該常數,則匯編器會生成適當的指令。如果不能用單個MOV或MVN 指令構造該常數,則匯編器會執行下列操作:將該值放入文字池中,生成一個使用程序相對地址的 LDR 指令,用于從文字池中讀取該常數。說的通俗一點,如果LDR Rd, =const能夠被轉換成MOV 或者MVN指令,則匯編器將轉換成它成為相應的指令,如果不能被轉換,則匯編器會將value存放在文字池中,并且產生一個LDR指令操作。
匯編器默認把文字池放在每一個代碼節的末尾處。代碼節的末尾的確定或者是由匯編源文件尾部的指示符END確定,或者由相鄰代碼節的起始行AREA確定。在大的代碼節中(通俗理解為這個節中的代碼量比較大),默認文字池在最后,可能與代碼節中一條或多條LDR偽指令的距離很遠,可能超出LDR偽指令操作數的尋址范圍。
當偽指令是32位時,在ARM或Thumb代碼中,必須小于4K字節,文字池常量數據的位置可以是在偽指令的前面,也可以是在偽指令的后面。當偽指令是16位Thumb指令時,必須小于1K字節,且文字池必須位于偽指令的后面。
LDR Rd, =const 偽指令需要一個文字池來存放立即數常量時,匯編器會檢查已經存在的文字池中是否有相同的常量并且檢查文字池是否在偽指令允許尋址的范圍內。如果條件滿足,匯編器引用這個滿足條件的常量,否則匯編器會嘗試把該常量值放到文字池未用的空間中。如果空間地址超出偽指令的尋址范圍,匯編器會產生一條錯誤信息。這種情況下,程序員必須得自己用指示符LTORG在代碼中設置增加一個文字池。指示符LTORG放在導致錯誤的偽指令后面,并且位于偽指令LDR的有效尋址范圍內(一般節的代碼量不是特別大的情況下,可以放于中間位置)。而且要保證設置的這個文字池,處理器執行代碼的時候不會執行到這個地址。它們應放在無條件跳轉指令的后面,或者放在子例程末尾處的返回指令的后面。
應用舉例如下:
Fun1
LDR R0, =0X12345678
ADD R1, R1, R0
BX LR ;子程序返回
LTORG ;聲明文字池,存儲0x12345678
POOL SPACE 20
好了,關于文字池,本片文章就講到這里了,大家有不明白的地方可以留言提問哦,謝謝大家。
責任編輯:haq
-
ARM
+關注
關注
134文章
9107瀏覽量
367976 -
編程
+關注
關注
88文章
3627瀏覽量
93809
原文標題:一文帶你讀懂ARM文字池
文章出處:【微信號:CanaanTech,微信公眾號:嘉楠科技】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論