280 likes | 635 Vues
第 四 章 ARM 組合語言. DMATEK CO.,LTD 深圳市長高科技有限公司. 本章節將介紹 ARM 指令集、 Thumb 指令集以及各類指令所對應的定址方式,透過對本文章的閱讀,希望讀者能瞭解 ARM 微處理器所支援的指令集及相關具體的使用方法。 本章的主要內容有: - ARM 指令集、 Thumb 指令集概述。 - ARM 指令集的分類與具體應用。 - Thumb 指令集簡介及應用場合。. 4-1 ARM 微處理器的指令集概述 : 4-1 . 1 ARM 微處理器的指令的分類與格式
E N D
第四章ARM組合語言 DMATEK CO.,LTD 深圳市長高科技有限公司
本章節將介紹ARM指令集、Thumb指令集以及各類指令所對應的定址方式,透過對本文章的閱讀,希望讀者能瞭解ARM微處理器所支援的指令集及相關具體的使用方法。本章節將介紹ARM指令集、Thumb指令集以及各類指令所對應的定址方式,透過對本文章的閱讀,希望讀者能瞭解ARM微處理器所支援的指令集及相關具體的使用方法。 本章的主要內容有: -ARM指令集、Thumb指令集概述。 -ARM指令集的分類與具體應用。 -Thumb指令集簡介及應用場合。
4-1 ARM微處理器的指令集概述: • 4-1.1 ARM微處理器的指令的分類與格式 • ARM微處理器的指令集是載入/存回做為基礎,也就是指令集僅能處理暫存器中的相關資料,且處理結果都需存回暫存器中,而對系統記憶體的存取則必需透通過透過專門的載入/存回指令來達成。 • ARM微處理器的指令集可以分為跳躍指令、資料處理指令、程式狀態暫存器(PSR)處理指令、載入/存回指令、輔助運算器指令和異常產生指令六大類,具體的指令及功能如表4-1所示(表中指令為基本ARM指令,不包括衍生的ARM指令)。
表表44-1 -1 ARMARM指令及功能描述一覽表指令及功能描述一覽表
4-1.2 指令的條件區域 • 當處理器工作在ARM狀態時,幾乎所有的指令均根據CPSR中條件碼欄位裡的各位元狀態與指令的條件的條件區域做有條件的執行(Conditional Execution)。當指令所執行的條件滿足時,指令將會被執行,否則指令就將被忽略。 • 因此,我們需要先加以整理指令的幾個相關重點: • -所有ARM指令都包括一個可選擇的條件碼,以{cond}來表示。 • -只要滿足CPSR的條件欄位所指定的條件時,符合這條件程式碼才可以被執行。 • 如下圖4-1列出一些部分指令程式碼所顯示的條件碼欄位示意圖。
圖4-1 列出部分的指令程式碼所顯示的條件碼欄位示意圖
在這當中,顯示每一條ARM指令包含4位元的條件碼,且位於指令的最高4位元[31:28]。條件碼共有16種,每個條件碼可用兩個字元表示,這兩個字元可以添加在指令附加字尾後面與指令同時使用。例如,跳躍指令B可以加上附加字尾EQ變為BEQ,表示了“相等則跳躍”,即當CPSR中的Z旗標位元被設定時,則發生跳躍。在這當中,顯示每一條ARM指令包含4位元的條件碼,且位於指令的最高4位元[31:28]。條件碼共有16種,每個條件碼可用兩個字元表示,這兩個字元可以添加在指令附加字尾後面與指令同時使用。例如,跳躍指令B可以加上附加字尾EQ變為BEQ,表示了“相等則跳躍”,即當CPSR中的Z旗標位元被設定時,則發生跳躍。 • 而在這16種條件標誌碼中,只有15種可以使用,如表4-2所示,第16種(1111)為系統保留,所以暫時不能使用。 • 表4-2 指令的條件碼
4-2 ARM指令的定址方式: • 所謂定址方式就是處理器根據指令中所給予的位址資訊來尋找出實體位址的方式。目前ARM指令系統支援如下幾種常見的定址方式。透過這些定址方式,可以讓讀者瞭解所要介紹的各種指令的類型,並加以相互比照對應。 • 4-2.1 立即定址 • 立即定址,這是一種特殊的定址方式,運算元本身是在指令中直接加以設定,只要取出指令也就取到了運算元。這個運算元被稱為立即數值,所以其對應的定址方式也就叫做立即定址。以下為指令的範例: ADD R0,R0,#1 ;R0←R0+1 ADDR0,R0,#0x3f ;R0←R0+0x3f
4-2.2 暫存器定址 • 暫存器定址就是利用暫存器中的數值作為運算元,這種定址方式是各類微處理器經常採用的一種方式,也是一種執行效率較高的定址方式,以下為指令的範例: ADDR0,R1,R2;R0←R1+R2 • 該指令的執行效果是將暫存器R1和R2的內容相加,並將結果存放於暫存器R0中。
4-2.3 暫存器間接定址 • 暫存器間接定址就是以暫存器中的值作為運算元的位址,而運算元本身是存放在記憶體位址中。以下為指令的範例: ADD R0,R1,[R2] ;R0←R1+[R2] LDR R0,[R1] ;R0←[R1] STR R0,[R1] ;[R1]←R0 • 在第一行條的指令中,以暫存器R2的值作為運算元的位址,在記憶體中取得一個運算元後與R1相加,結果存入R0的暫存器中。第二行指令是載入的指令,將R1的值作為位址的記憶體中的資料,然後傳送到R0暫存器中。而第三行的指令是存回指令,是將R0的數值傳送到以R1的數值為位址的記憶體中。
4-2.4 基底定址 • 基底定址就是將暫存器(該暫存器一般稱之為基底暫存器)的內容與指令中給予的位址偏移量然後加以相加,進而得到一個運算元的有效位址。基底定址方式常用於存取某基底位址附近的記憶體區域,此包含了基底加上偏移量,以及基底加上索引值等來定址的方式。 • 這跟之後所要介紹的暫存器定址相當類似,只不過後者是偏移量為0而已。而基底加上偏移量所定址之用的基底暫存器包含了並非是正確的位址。這基底暫存器需加上或是減掉最大達4KB的偏移量來計算出所要存取的位址。以下為指令的範例: LDR R0,[R1,#4] ;R0←[R1+4] • 這是前索引定址的方式。我們將透過一個基底暫存器來存取同一個記憶體區域的某個記憶體單元的內容。在這指令中,我們可以將暫存器R1的內容加上4後形成一個有效位址,然後從此位址的記憶體中取得數值後,再存入暫存器R0中。
除此之外,除了上述所使用的方法外,我們還可以透過基底定址的方式,除了找到基底定址所指向的記憶體區域外,還可去改變這基底的暫存器。以下為指令的範例:除此之外,除了上述所使用的方法外,我們還可以透過基底定址的方式,除了找到基底定址所指向的記憶體區域外,還可去改變這基底的暫存器。以下為指令的範例: LDR R0,[R1,#4]! ;R0←[R1+4]、R1←R1+4 • 即可改變基底暫存器來指向下一個要傳送的位址,這對多筆的資料傳送是很有用途。這是一種包含自動索引的前索引定址方式。其中,“!”符號是表示指令在完成資料傳送後,還需更新基底的暫存器。然而ARM微處理器對於這種自動索引的方式,是不會消耗額外的週期時間。 • 而還有另一種基底加偏移定址的方式,則稱之為後索引定址。即是一種基底不包含偏移量來作為傳送的位址,當傳送後,自動加上索引的方式。以下為指令的範例: LDR R0,[R1] ,#4 ;R0←[R1]、R1←R1+4
在這裡沒有使用“!”符號,只運用了立即數值的偏移來作為基底暫存器的變化量。在這裡沒有使用“!”符號,只運用了立即數值的偏移來作為基底暫存器的變化量。 • 除此之外,基底加上索引定址的方式是在指令中設定一個暫存器,然後再去指定另外一個暫存器(作為索引之用),而這後面的數值可作為位移到基底位址上而形成一個記憶體位址。以下為指令的範例: LDR R0,[R1,R2] ;R0←[R1+R2] • 這個指令是將R1與R2的內容相加而得到的運算元位址,再將此位址所指定的記憶體的內容傳送至R0。而上述的這4個指令都是屬於存回的指令。 • 在以上兩條指令中,第二個來源運算元即為立即常數,要求以“#”為首碼,而對於以十六進位表示的立即常數,還要求在“#”後加上“0x”或“&”。
4-2.5 相對定址 • 與基底定址方式相類似,相對定址是以程式計數器PC的目前數值作為基底位址,指令中的位址標號作為偏移量,而將兩者相加之後得到有效位址。以下所列的程式段完成了副程式的跳躍與返回,其中,跳躍指令,BL採用了相對定址方式: BLNEXT ;跳躍到副程式NEXT處執行 …… NEXT …… MOV PC,LR;從副程式返回
4-2.6 多暫存器定址 • 採用多暫存器定址方式,一條指令可以完成多個暫存器值的傳送。這種定址方式可以用一條指令完成傳送最多16個通用暫存器的值。 • 如下,舉出一個指令的範例: LDMIA R0,{R1,R2,R3,R4} ;R1←[R0] ;R2←[R0+4] ;R3←[R0+8] ;R4←[R0+12] • 該指令的尾碼IA表示在每次執行完載入/存回操作後,R0按字元組長度增加,因此,這個指令可將連續記憶體單元的數值傳送到R1~R4。稍後,我們會再進一步地說明這個指令的用法。
4-2.7 堆疊定址 • 堆疊是一種資料結構,按先進後出(First In Last Out,FILO)的方式工作,使用一個稱作堆疊指標的專用暫存器來指示當前的操作位置,堆疊指標總是指向堆疊的頂端。 • 當堆疊指標指向最後所填入堆疊的資料時,稱為滿堆疊(Full Stack),而當堆疊指標指向下一個將要放入資料的空位置時,稱為空堆疊(Empty Stack)。 • 同時,根據堆疊的生成方式,又可以分為遞增堆疊(Ascending Stack)和遞減堆疊(Decending Stack)。當堆疊由低位址向高位址生長時,稱為遞增堆疊,反之,當堆疊由高位址向低位址生長時,稱為遞減堆疊。這樣就有四種類型的堆疊工作方式,所以ARM微處理器支援這四種類型的堆疊工作方式,即:
- 滿遞增堆疊:堆疊指標指向最後填入的資料,且由低位址向高位址生長。- 滿遞增堆疊:堆疊指標指向最後填入的資料,且由低位址向高位址生長。 • - 滿遞減堆疊:堆疊指標指向最後填入的資料,且由高位址向低位址生長。 • - 空遞增堆疊:堆疊指標指向下一個將要放入資料的空位置,且由低位址向高地址生長。 • - 空遞減堆疊:堆疊指標指向下一個將要放入資料的空位置,且由高位址向低地址生長。
4-3組合程言程式設計: • 上述的組合語言介紹以了解組合語言基本語法,在下面的章節我們以兩個例子來說明講解。 • 1.HELLO程式 • 2.簡易LED控制 • 4-3.1 Hello程式 • 以下範例程式是列印出HELLO WORLD的字串。 AREA ASM1,CODE,READONLY ;定義一個程式區段,區段名稱為 ;名稱為ASM1,屬性唯讀 ENTRY ;程式的入口點 虛擬指令 START mov r0,#0x3 將0x3這個值傳送到r0 ldr r1,=str1 ;將str1的位址存放到暫存器r0中 printstr swi 0x123456 ;在0x123456位址設置軟體中斷點
add r1,r1,#1 ;r1=r1+1 ldrb r2,[r1] cmp r2,#0 ;將r2的值與0相比較 bne printstr ;比較結果r2不為0,繼續這個迴圈 stop mov r0,#0x18 ;將0x18的位址 ldr r1,=0x20026 ;將0x2006的位址存放到暫存器r1中 swi 0x123456 ;在0x123456設置中斷點 area strdata,data,readonly ;定義一個程式區段,區段名稱為 ;名稱為strdata,屬性唯讀 str1 dcb "Hello World", 0 ;宣告連續記憶區塊將字串” Hello World”; 傳給str1位址 end
圖4-2 Hello World程式的輸出結果 • 程式執行結果如下圖4-2所示,為Hello World程式的輸出結果:
4-3.2簡易LED控制 • 使用是以2440XP平台,以下範例程式是簡單控制LED燈的亮滅,使用BL指令呼叫程式的組合語言基本結構。 rGPFCON EQU 0x56000050;定義S3C2440 GPIO的位址 rGPFDAT EQU 0x56000054 rGPFUP EQU 0x56000058 AREA Init,CODE,READONLY;該虛擬指令定義了一個程式區段,區段名稱為 ;Init,屬性唯讀 ENTRY ;程式的入口點 虛擬指令 ;= = = =設置I/O埠GPF5為輸出屬性= = = = = ldr r0,=rGPFCON;將暫存器rPCONF的位置存放到暫存器r0中 ldr r1,=0x400 str r1,[r0] ;將r1中的資料存放到暫存器Rpconf中
;下面3個指令,主要是取消GPF埠的提升電阻 ldr r0;=rGPFUP ldr r1,=0xffff str r1,[ r0] dr r2,=rGPFDAT ;將資料埠F的資料暫存器的位址附給暫存器r2 loop ldr r1,=0xff str r1,[r2] ;使GPE5輸出高電壓,LED1燈滅 bl delay ;呼叫延遲副程式 ldr r1,=0x0 str r1,[r2] ;使GPE5輸出低電壓,LED1燈亮 bl delay ;呼叫延遲 b loop ;不斷的迴圈,LED1將不停的閃爍
;delay 延遲副程式 delay ldr r3,=0xaffff ;設置延遲的時間 delay1 sub r3,r3,#1 ;r3=r3-1 cmp r3,#0x0 ; ;將r3的值與0相比較 bne delay1 ;比較結果不為0(r3不為0),繼續呼叫delay1,否則 ;執行下一個指令 mov pc,lr ;從副程式返回 END ;程式結束
4-4 問題與討論: • 一、何謂有條件的執行? • 二、ARM 支援那些定址模式。 • 三、試著改寫Hello的程式,使其能支援輸出兩個字串。【提示:增列宣告str2】 • 四、改寫簡易LED控制程式使其奇偶數燈號交互閃爍。