250 likes | 561 Views
微處理機系統 (Microprocessor System). 第四章 ARM 程式設計基礎. Ping-Liang Lai ( 賴秉樑 ). 章節大綱. 4.1 ARM 編譯器所支援的虛擬指令 4.2 組合語言的語法 4.3 組合語言的程式結構. 4.1 ARM 編譯器所支援的虛擬指令. 虛擬指令 : 一些特殊指令助記符號,這些助記符號與指令系統的助記符號不同,沒有相對應的運算碼 (op-code) ,通常稱這些特殊指令助記符為虛擬指令,他們所完成的操作稱之為偽操作。 為完成組合語言程式做各種準備工作 ;
E N D
微處理機系統(Microprocessor System) 第四章ARM 程式設計基礎 Ping-Liang Lai (賴秉樑)
章節大綱 • 4.1 ARM 編譯器所支援的虛擬指令 • 4.2 組合語言的語法 • 4.3 組合語言的程式結構
4.1 ARM 編譯器所支援的虛擬指令 • 虛擬指令: 一些特殊指令助記符號,這些助記符號與指令系統的助記符號不同,沒有相對應的運算碼 (op-code),通常稱這些特殊指令助記符為虛擬指令,他們所完成的操作稱之為偽操作。 • 為完成組合語言程式做各種準備工作; • 僅於編譯過程起作用,編譯結束,虛擬指令的使命便完成。 • 虛擬指令的種類 • 符號定義虛擬指令; • 資料定義虛擬指令; • 編譯控制虛擬指令; • 巨集指令; • 其他虛擬指令。
符號定義虛擬指令 • 符號定義虛擬指令: 用於定義 ARM 組合語言中的變數、對變數設定值以及定義暫存器的別名等操作。 • 符號定義虛擬指令的種類 • 用於定義整體變數的 GBLA 、 GBLL 和 GBLS; • 用於定義區域變數的 LCLA 、 LCLL 和 LCLS; • 用於對變數設定值的 SETA 、 SETL 和 SETS; • 為通用暫存器列表定義名稱的 RLIST。
GBLA 、 GBLL 和 GBLS • 語法格式 GBLA(GBLL 或 GBLS) 整體變數名稱 • GBLA 、 GBLL 和 GBLS 虛擬指令用於定義一個 ARM 程式中的整體變數,並將其初使化。其中: • GBLA 用於定義一個整體的數位變數,並初使化為0; • GBLL 用於定義一個整體的邏輯變數,並初使化為F(假值); • GBLS 用於定義一個整體的字串變數,並初使化為空字串; • 程式範例 GBLA Test1 ;定義一個整體的數位變數,名稱為 Test1 Test1 SETA 0xaa ;將該變數設定值為 0xaa GBLL Test2 ;定義一個整體的邏輯變數,名稱為 Test2 Test2 SETL {True} ;將該變數設定值為真 GBLS Test3 ;定義一個整體的字串變數,名稱為 Test3 Test3 SETS “Testing” ;將該變數設定值為 “Testing”
LCLA 、 LCLL 和 LCLS • 語法格式 LCLA(LCLL 或 LCLS) 整體變數名稱 • LCLA 、 LCLL 和 LCLS: 虛擬指令用於定義一個 ARM 程式中的區域變數,並將其初使化。其中: • LCLA 用於定義一個區域的數位變數,並初使化為0; • LCLL 用於定義一個區域的邏輯變數,並初使化為F(假值); • LCLS 用於定義一個區域的字串變數,並初使化為空字串; • 程式範例 LCLA Test4 ;定義一個區域的數位變數,名稱為 Test4 Test4 SETA 0xaa ;將該變數設定值為 0xaa LCLL Test5 ;定義一個區域的邏輯變數,名稱為 Test5 Test5 SETL {True} ;將該變數設定值為真 LCLS Test6 ;定義一個區域的字串變數,名稱為 Test6 Test6 SETS “Testing” ;將該變數設定值為 “Testing”
章節大綱 • 4.1 ARM 編譯器所支援的虛擬指令 • 4.2 組合語言的語法 • 4.3 組合語言的程式結構
4.2 組合語言的語法 • 組合語言的語法 {標記} {指令或虛擬指令} {運算元} {;注解} • 範例 標記運算碼 運算元 注解 ---------- ----------- ----------- ---------- BL NEXT ;跳躍到副程式NEXT處執行 ….. NEXT ….. MOV PC, LR ;從副程式返回 指令符號可大小寫,但不可混合使用
程式中的變數 • 程式中的變數是指其值在程式的執行過程中可以改變其數量。 • ARM(Thumb)支援的變數 • 數位變數: 用於程式執行中所保存的數位數值,大小不應超過所能表示數位變數的範圍; • 邏輯變數: 用於程式執行中所保存的邏輯數值,只有真或假兩種情況; • 字串變數: 用於程式執行中所保存的一個字串,大小不應超過所能表示字串變數的範圍。 • 宣告整體變數的指令: GBLA 、 GBLL 、 GBLS • 宣告區域變數的指令: LCLA 、 LCLL 、 LCLS • 變數初使化的指令: SETA 、 SETL 、 SETS
程式中的常數 • 程式中的常數是指其值在程式的執行過程中不能改變其數量。 • ARM(Thumb)支援的常數 • 數位常數: 一般為32位元的整數,當無號數時,其數值範圍為 0 ~ 232-1,當有號數時,其數值範圍為 -231 ~ 231-1; • 邏輯常數: 只有真或假兩種情況; • 字串常數: 為一固定的字串,一般用於程式執行時的訊息提示。
程式中的變數替換 • 程式中的變數可通過替換操作來取得一個常數,替換操作符號為 “$”。 • “$” 在變數前代表的意義 • 數位變數: 編譯器會將數位變數的數值轉換成16進位的字串,並將該16進位的字串來替換 “$” 後的數位變數; • 邏輯變數: 編譯器會將邏輯變數替換成它的邏輯值 (真或假); • 字串變數: 編譯器會將字串變數的值來替換 “$” 後的字串變數。 • 程式範例 LCLS S1 ;定義字串變數 S1 LCLS S2 ;定義字串變數 S2 S1 SETS “Test!” S2 SETS “This is a $S1” ;字串變數 S2 的值為 “This is a Test!”
運算式與運算子 • 運算式: 一般由變數、常數與運算子和括弧所構成。 • 常用的運算式有數位運算式、邏輯運算式與字串運算式,其運算優先順序如下規則: • 優先順序相同的雙運算子的運算順序為從左到右; • 相鄰的單運算子的運算順序為從右到左,且單運算子的優先順序高於其他運算子; • 括弧內運算子的優先順序最高。
數位運算式與運算子 (1/2) • 數位運算式: 由數位變數、數位常數、數位運算子和括弧所構成。 • 與數位運算式相關的運算子: “+”、“-”、“×”、“/” 及 “MOD” 算術運算子。 • 範例: 以 X 與 Y 表示兩個數字的數位運算式 • X + Y ;表示X與Y的和 • X - Y ;表示X與Y的差 • X×Y ;表示X與Y的乘積 • X/Y ;表示X與Y的商 • X:MOD:Y ;表示X與Y的餘數
數位運算式與運算子 (2/2) • 移位運算子: “ROL”、“ROR”、“SHL”、“SHR”。 • 範例範例: 以 X 與 Y 表示兩個數字運算式,以上移位運算子所代表的運算如下 • X:ROL:Y ;表示將 X 左旋轉移 Y 位 • X:ROR:Y ;表示將 X 右旋轉移 Y 位 • X:SHL:Y ;表示將 X 左移 Y 位 • X:SHR:Y ;表示將 X 右移 Y 位 • 位元邏輯運算子: “AND”、“OR”、“NOT”、“EOR”。 • 範例範例: 以 X 與 Y 表示兩個數字運算式 • X:AND:Y ;表示將 X 和 Y 按位元作邏輯 AND 的操作 • X:OR:Y ;表示將 X 和 Y 按位元作邏輯 OR 的操作 • :NOT:Y ;表示將 Y 按位元作邏輯 NOT 的操作 • X:EOR:Y ;表示將 X 和 Y 按位元作邏輯 XOR 的操作
邏輯運算式與運算子 (1/2) • 邏輯運算式: 由邏輯量、邏輯運算子和括弧所構成,其運算結果為真或假值。 • 與邏輯運算式相關的運算子: “=”、“>”、“<”、“>=”、“<=”、“/=”、“<>” 運算子。 • 範例: 以 X 與 Y 表示兩個邏輯運算式 • X=Y ;表示 X 等於 Y • X>Y ;表示 X 大於 Y • X<Y ;表示 X 小於 Y • X>=Y ;表示 X 大於等於 Y • X<=Y ;表示 X 小於等於 Y • X/=Y ;表示 X 不等於 Y • X<>Y ;表示 X 不等於 Y
邏輯運算式與運算子 (2/2) • “LAND”、“LOR”、“LNOT”、“LEOR” 運算子。 • 範例: 以 X 與 Y 表示兩個邏輯運算式 • X:LAND:Y ;表示將 X 和 Y 作邏輯 AND 的操作 • X:LOR:Y ;表示將 X 和 Y 作邏輯 OR 的操作 • :LNOT:Y ;表示將 Y 作邏輯 NOT 的操作 • X:LEOR:Y ;表示將 X 和 Y 作邏輯 XOR 的操作
字串運算式與運算子 (1/2) • 字串運算式: 由字串變數、字串常數、運算子和括弧所構成,編譯器所支援的字串最大長度為 512 位元組。 • 與字串運算式相關的運算子: “LEN”、“CHR”、“STR”、“LEFT”、“RIGHT”、“CC” 運算子。 • 範例: • LEN 運算子: 返回字串的長度 (字元數),以 X 表示字串運算式,其語法如下: :LEN:X • CHR 運算子: 將 0 ~ 255 之間的整數轉換為一個字元,以 M 表示某一個整數,其語法如下: :CHR:M • STR 運算子: 將一個數位運算式或邏輯運算式轉換為一個字串。對於數位運算式,STR 將其轉換為一個以 16 進位組成的字串; 對於邏輯運算式,STR 將其轉換為字串 T 或 F,其語法如下: :STR:X 其中,X 為一個數位運算式或邏輯運算式。
字串運算式與運算子 (2/2) • 範例: • LEFT 運算子: 返回某個字串左端的一個子串,其語法如下: X:LEFT:Y 其中,X 為來源字串,Y 為一個整數,表示要返回的字元個數。 • RIGHT 運算子: 返回某個字串右端的一個子串,其語法如下: X:RIGHT:Y 其中,X 為來源字串,Y 為一個整數,表示要返回的字元個數。 • CC 運算子: 將兩個字串連接成一個字串,其語法如下: X:CC:Y 其中,X 為來源字串1,Y 為來源字串2,CC 運算子將 Y 連接到 X 的後面。
與暫存器和 PC 相關的運算式與運算子 • BASE 運算子: 返回基於暫存器的運算式中暫存器的編號 ,其語法如下: :BASE:X 其中,X 為與暫存器相關的運算式。 • INDEX 運算子: 返回基於暫存器的運算式中,相對於基底暫存器的偏移量 ,其語法如下: :INDEX:X 其中,X 為與暫存器相關的運算式。
其他常用運算子 • ? 運算子: 返回某代碼行所產生的可執行程式代碼的長度,其語法如下: ?X 返回定義符號 X 的程式代碼行所產生的可執行代碼的位元組數。 • DEF 運算子: 判斷是否定義某個符號,其語法如下: :DEF:X 如果符號 X 已經定義,則結果為真,否則為假。
章節大綱 • 4.1 ARM 編譯器所支援的虛擬指令 • 4.2 組合語言的語法 • 4.3 組合語言的程式結構
4.3 組合語言的程式結構 (1/4) • 基本程式結構 AREA Init, CODE, READONLY ENTRY Start LDR R0, =0x3FF5000 LDR R1, 0xFF STR R1, [R0] LDR R0, =0x3FF5008 LDR R1, 0x01 STR R1, [R0] ----- END
4.3 組合語言的程式結構 (2/4) • 副程式呼叫 AREA Init, CODE, READONLY ENTRY Start LDR R0, =0x3FF5000 LDR R1, 0xFF STR R1, [R0] LDR R0, =0x3FF5008 LDR R1, 0x01 STR R1, [R0] BL PRINT_TEXT ----- PRINT_TEXT ----- MOV PC, BL ----- END
4.3 組合語言的程式結構 (3/4) • 若是所有的程式設計都是透過組合語言,其工作量是相當繁重的。 • ARM 系列結構支援 C/C++以及與組合語言的混合撰寫,在一個完整的程式設計中,除了初始化部分用組合語言外,其餘主要的程式設計工作一般都是用C/C++ 來撰寫的。 • 幾種混合的方式: • 在 C/C++ 程式代碼中嵌入編譯指令; • 在組合語言程式和 C/C++ 的程式之間進行變數的相互存取; • 在組合語言程式。、 C/C++ 的程式之間相互呼叫。
4.3 組合語言的程式結構 (4/4) • 組合語言與 C/C++ 的混合設計 IMPORTMain ;通知編譯器該標記為一個外部標記 AREA Init, CODE, READONLY ;定義一個程式代碼段 ENTRY ;定義程式的入口點 LDR R0, =0x3FF0000 ;初始化系統配置暫存器,具體內容可參考第五、六章 LDR R1, =0xE7FFFF80 TR R1, [R0] LDR SP, =0x3FE1000 ;初始化使用者堆疊,具體內容可參考第五、六章 BL Main ;跳躍到 Main ( ) 函數處的 C/C++代碼執行 END ;標示出組合語言程式的結束處 void Main(void) { int i; *((volatile unsigned long *) 0x3ff5000) = 0x0000000f; while(1) { *((volatile unsigned long *) 0x3ff5008) = 0x00000001; for(i=0; i<0x7fFFF; i++); *((volatile unsigned long *) 0x3ff5008) = 0x00000002; for(i=0; i<0x7fFFF; i++); } }