




已閱讀5頁,還剩112頁未讀, 繼續(xù)免費閱讀
版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
第3章ARM指令系統(tǒng) 硅谷芯微技術貢獻網(wǎng)址 www threeway cc 面對復雜多變的ARM匯編指令表 本章重點介紹實用價值大 有一定難度且理解起來容易出錯的指令 以點帶面達到全面掌握ARM匯編指令的目的 第3章目錄 1 ARM處理器尋址方式2 指令集介紹3 課后練習 3 1ARM處理器尋址方式 ARM處理器是基于精簡指令集計算機 RISC 原理設計的 指令集和相關譯碼機制較為簡單 ARM9TDMI S 具有32位ARM指令集和16位Thumb指令集 ARM指令集效率高 但是代碼密度較低 而Thumb指令集具有較高的代碼密度 并且保持ARM的大多數(shù)性能上的優(yōu)勢 它是ARM指令集的子集 所有的ARM指令都是可以有條件執(zhí)行的 而Thumb指令僅有一條指令 分支指令B 具備條件執(zhí)行功能 ARM程序和Thumb程序可相互調用 相互之間的狀態(tài)切換開銷幾乎為零 說明 本章中的ARM9TDMI S 表示ARM9TDMI或ARM9TDMI S 尋址方式是根據(jù)指令中給出的地址碼字段來實現(xiàn)尋找真實操作數(shù)地址的方式 ARM處理器具有8種基本尋址方式 3 1 1寄存器尋址 寄存器尋址是指操作數(shù)的值在寄存器中 指令中的地址碼字段指出的是寄存器編號 指令執(zhí)行時直接取出寄存器值來操作 應用示例 3 1 2立即尋址 立即尋址指令中的操作碼字段后面的地址碼部分即是操作數(shù)本身 也就是說 數(shù)據(jù)就包含在指令當中 取出指令也就取出了可以立即使用的操作數(shù) 這樣的數(shù)稱為立即數(shù) 應用示例 3 1 3寄存器移位尋址 1 寄存器移位尋址是ARM指令集特有的尋址方式 當?shù)?個操作數(shù)是寄存器移位方式時 第2個寄存器操作數(shù)在與第1個操作數(shù)結合之前 選擇進行移位操作 應用示例 可采用的移位操作如下 LSL 邏輯左移 LogicalShiftLeft 寄存器中字的低端空出的位補0 LSR 邏輯右移 LogicalShiftRight 寄存器中字的高端空出的位補0 ASR 算術右移 ArithmeticShiftRight 移位過程中保持符號位不變 若源操作數(shù)為正數(shù) 則字的高端空出的位補0 否則補1 3 1 3寄存器移位尋址 2 ROR 循環(huán)右移 ROtateRight 由字的低端移出的位填入字的高端空出的位 RRX 帶擴展的循環(huán)右移 RotateRighteXtendedby1place 操作數(shù)右移1位 高端空出的位用原C標志值填充 各種移位操作如圖3 1所示 圖3 1移位操作示意圖 3 1 4寄存器間接尋址 寄存器間接尋址指令中的地址碼給出的是一個通用寄存器的編號 所需的操作數(shù)保存在寄存器指定地址的存儲單元中 即寄存器為操作數(shù)的地址指針 應用示例 3 1 5基址尋址 基址尋址就是將基址寄存器的內容與指令中給出的偏移量相加 形成操作數(shù)的有效地址 基址尋址用于訪問基址附近的存儲單元 常用于查表 數(shù)組操作 功能部件寄存器訪問等 應用示例 3 1 6多寄存器尋址 多寄存器尋址是指一次可傳送幾個寄存器值 允許一條指令傳送16個寄存器的任何子集或所有寄存器 應用示例 3 1 7堆棧尋址 1 在2 5 1小節(jié)的 堆棧指針 SP 中介紹了堆棧的定義和作用 接下來講述堆棧在ARM9中的特性 前面講過對堆棧操作都是通過堆棧指針 SP 來進行的 隨著堆棧內容的增減 堆棧指針也做相應的移動 那么有個問題 當寫入數(shù)據(jù)時堆棧指針是如何變化的呢 堆棧指針的移動方向稱之為 堆棧的生長方向 ARM9可以支持2種 如圖3 2所示 向上生長 在向堆棧寫入數(shù)據(jù)后 堆棧指針的值變大 也就是向高地址方向生長 稱之為遞增堆棧 向下生長 在向堆棧寫入數(shù)據(jù)后 堆棧指針的值變小 也就是向低地址方向生長 稱之為遞減堆棧 3 1 7堆棧尋址 2 圖3 2堆棧的生長方向 3 1 7堆棧尋址 3 除了要考慮堆棧指針的增長方向之外 還要考慮堆棧指針指向的存儲單元是否已經(jīng)保存有堆棧數(shù)據(jù) 或者說在入棧時是否可以直接向堆棧指針指向的存儲單元寫入數(shù)據(jù) ARM9支持2種情況 分別為 滿堆棧 和 空堆棧 如圖3 3所示 滿堆棧 堆棧指針指向最后壓入的有效數(shù)據(jù)項 稱為滿堆棧 這種堆棧的入棧操作要先調整指針再寫入數(shù)據(jù) 空堆棧 堆棧指針指向下一個待壓入數(shù)據(jù)的空位置 稱為空堆棧 這種堆棧的入棧操作要先寫入數(shù)據(jù)再調整指針 3 1 7堆棧尋址 4 圖3 3堆棧的滿空特性 3 1 7堆棧尋址 5 綜合前面的堆棧生長方向和堆棧的滿空特性 可以得到4種堆棧類型 分別為 滿遞增 堆棧通過增大存儲器的地址向上增長 堆棧指針指向內含有有效數(shù)據(jù)項的最高地址 如指令LDMFA STMFA等 空遞增 堆棧通過增大存儲器的地址向上增長 堆棧指針指向堆棧上的第一個空位置 如指令LDMEA STMEA等 滿遞減 堆棧通過減小存儲器的地址向下增長 堆棧指針指向內含有有效數(shù)據(jù)項的最低地址 如指令LDMFD STMFD等 空遞減 堆棧通過減小存儲器的地址向下增長 堆棧指針指向堆棧下的第一個空位置 如指令LDMED STMED等 3 1 7堆棧尋址 6 應用示例 3 1 8相對尋址 相對尋址是基址尋址的一種變通 由程序計數(shù)器PC提供基準地址 指令中的地址碼字段做為偏移量 兩者相加后得到的地址即為操作數(shù)的有效地址 應用示例 3 2指令集介紹 本節(jié)介紹ARM9TDMI S 的指令集 包括ARM指令集和Thumb指令集 首先介紹ARM指令的基本格式及靈活的操作數(shù) 然后介紹條件碼 重點介紹ARM指令集 對Thumb指令集 僅作簡要介紹 在介紹ARM指令集之前 先看一個簡單的ARM匯編程序 了解有關ARM指令匯編格式 程序結構和基本風格 完整代碼如程序清單3 1所示 程序清單3 1寄存器相加 第 行為程序說明 使用分號 進行注釋 分號 號后面至行結束均為注釋內容 第 行聲明一個代碼段 ARM匯編程序至少要聲明一個代碼段 第 行標識程序入口 在仿真調試時會從指定入口處開始運行程序 第 行聲明32位ARM指令 ARM9TDMI S 復位后是ARM狀態(tài) 第 行為實際代碼 標號要頂格書寫 如START LOOP ADD SUB 而指令不能頂格書寫 BL為調用子程序指令 它會把返回地址 即下一條指令的地址 存到LR 然后跳轉到子程序ADD SUB 子程序ADD SUB處理結束后 將LR的值裝入PC即可返回 第 行為空行 目的在于增強程序的可讀性 第 行用于指示匯編文件結束 每一個ARM匯編文件均要用END聲明結束 3 2 1ARM指令集 ARM指令集為32位字對齊指令集 效率高但代碼密度較低 這是本章的重點 3 2 1 1指令格式 1 ARM指令的基本格式如下 S S 其中 號內的項是必需的 號內的項是可選的 例如是指令助記符 這是必須書寫的 而 為指令執(zhí)行條件 是可選項 若不書寫則使用默認條件AL 無條件執(zhí)行 opcode 指令助記符 如LDR STR等 cond 執(zhí)行條件 如EQ NE等 參考表3 1 S 是否影響CPSR寄存器的值 書寫時影響CPSR Rd 目標寄存器 3 2 1 1指令格式 2 Rn 第1個操作數(shù)的寄存器 operand2 第2個操作數(shù) 指令格式應用舉例 在ARM指令中 靈活地使用第2個操作數(shù)能夠提高代碼效率 第2個操作數(shù)有如下幾種形式 1 immed 8r 常數(shù)表達式 該常數(shù)必須對應8位位圖 pattern 即常數(shù)是由一個8位的常數(shù)循環(huán)移位偶數(shù)位得到的 3 2 1 1指令格式 3 合法常量 0 x3FC 0 xFF 2 0 0 xF0000000 0 xF0 24 200 0 xC8 0 xF0000001 0 x1F 28 非法常量 0 x1FE 511 0 xFFFF 0 x1010 0 xF0000010 常數(shù)表達式應用舉例 2 Rm 寄存器方式 在寄存器方式下 操作數(shù)即為寄存器的數(shù)值 3 2 1 1指令格式 4 寄存器方式應用舉例 3 Rm shift 寄存器移位方式 將寄存器的移位結果作為操作數(shù) 但Rm值保持不變 移位方法如下 ASR n 算術右移n位 1 n 32 LSL n 邏輯左移n位 1 n 31 LSR n 邏輯右移n位 1 n 32 RRX 帶擴展的循環(huán)右移1位 typeRs type為ASR LSL LSR和ROR中的一種 Rs為偏移量寄存器 低8位有效 若Rs值大于或等于32 則第2個操作數(shù)的結果為0 ASR ROR例外 3 2 1 1指令格式 5 寄存器移位方式應用舉例 R15為處理器的程序計數(shù)器PC 一般不要對其進行操作 而且有些指令是不允許使用R15的 如UMULL指令 3 2 1 2條件碼 1 使用指令條件碼可實現(xiàn)高效的邏輯操作 提高代碼執(zhí)行效率 所有的指令條件碼如表3 1所列 表3 1指令條件碼列表對于Thumb指令集 只有B指令具有條件碼執(zhí)行功能 此指令的條件碼同表3 1 但如果為無條件執(zhí)行時 條件碼助記符AL不能在指令中書寫 3 2 1 2條件碼 2 應用示例 比較兩個值大小 并進行相應加1處理 C代碼如下 對應的ARM指令如下 其中R0為a R1為b 若兩個條件均成立 則將這兩個數(shù)值相加 C代碼如下 3 2 1 2條件碼 3 對應的ARM指令如下 其中R0為a R1為b 3 2 1 3ARM存儲器訪問指令 1 ARM處理器是RISC架構的處理器 它無法像CISC架構的處理器一樣讓存儲器中的內容直接參與運算 而是需要將存儲單元的內容先讀取到內部寄存器中 ARM處理器是加載 存儲體系結構的典型RISC處理器 對存儲器的訪問只能使用加載和存儲指令實現(xiàn) ARM的加載 存儲指令可實現(xiàn)字 半字 無符號字節(jié)和有符號字節(jié)的操作 多寄存器加載 存儲指令可實現(xiàn)一條指令加載 存儲多個寄存器的內容 大大提高了效率 SWP指令是一條寄存器和存儲器內容交換的指令 可用于信號量操作等 ARM處理器是馮 諾依曼體系結構 程序空間 RAM空間及I O映射空間統(tǒng)一編址 對這些空間的訪問均須通過加載 存儲指令進行 ARM存儲器訪問指令如表3 2所列 3 2 1 3ARM存儲器訪問指令 2 表3 2ARM存儲器訪問指令 3 2 1 3ARM存儲器訪問指令 3 1 LDR STR 加載 存儲指令 LDR指令用于從內存中讀取數(shù)據(jù)放入寄存器中 STR指令則相反 它用于將寄存器中的數(shù)據(jù)保存到內存中 LDR和STR指令搭配不同的后綴可以實現(xiàn)字節(jié) 半字或字數(shù)據(jù)的訪問 加載 存儲字和無符號字節(jié)指令 指令格式 LDR cond T Rd 加載指定地址上的數(shù)據(jù) 字 放入Rd中STR cond T Rd 存儲數(shù)據(jù) 字 到指定地址的存儲單元 要存儲的數(shù)據(jù)在Rd中LDR cond B T Rd 加載字節(jié)數(shù)據(jù) 放入Rd中 即Rd最低字節(jié)有效 高24位清零 3 2 1 3ARM存儲器訪問指令 4 STR cond B T Rd 存儲字節(jié)數(shù)據(jù) 要存儲的數(shù)據(jù)在Rd 最低字節(jié)有效其中 T為可選后綴 若指令有T 那么即使處理器是在特權模式下 存儲系統(tǒng)也將訪問看成是處理器是在用戶模式下 T在用戶模式下無效 不能與前索引偏移一起使用T LDR STR指令尋址是非常靈活的 由兩部分組成 一部分為一個基址寄存器 可以為任一個通用寄存器 另一部分為一個地址偏移量 它有3種格式 a 立即數(shù) 立即數(shù)可以是一個無符號的數(shù)值 這個數(shù)據(jù)可以加到基址寄存器 也可以從基址寄存器減去這個數(shù)值 3 2 1 3ARM存儲器訪問指令 5 應用示例 b 寄存器 寄存器中的數(shù)值可以加到基址寄存器 也可以從基址寄存器中減去這個數(shù)值 應用示例 3 2 1 3ARM存儲器訪問指令 6 c 寄存器與移位常數(shù) 寄存器移位后的值可以加到基址寄存器 也可以從基址寄存器中減去這個數(shù)值 應用示例 從尋址方式的地址計算方法分 加載 存儲指令有以下4種形式 零偏移 Rn的值作為傳送數(shù)據(jù)的地址 即地址偏移量為0 應用示例 3 2 1 3ARM存儲器訪問指令 7 b 前索引偏移 在數(shù)據(jù)傳送之前 將偏移量加到Rn中 其結果作為傳送數(shù)據(jù)的存儲地址 若使用后綴 則結果寫回到Rn中 且Rn的值不允許為R15 應用示例 c 程序相對偏移 程序相對偏移是前索引形式的另一個版本 匯編器由PC寄存器計算偏移量 并將PC寄存器作為Rn生成前索引指令 不能使用后綴 應用示例 3 2 1 3ARM存儲器訪問指令 8 說明 label為程序標號 label必須是在當前指令的 4KB范圍內 d 后索引偏移 Rn的值用作傳送數(shù)據(jù)的存儲地址 在數(shù)據(jù)傳送后 將偏移量與Rn相加 結果寫回到Rn中 Rn不允許是R15 應用示例 地址對齊 大多數(shù)情況下 必須保證用于32位傳送的地址是32位地址對齊的 3 2 1 3ARM存儲器訪問指令 9 加載 存儲半字和有符號字節(jié) 指令格式 LDR cond SBRd 加載指定地址上的數(shù)據(jù) 有符號字節(jié) 放入Rd中LDR cond SHRd 加載指定地址上的數(shù)據(jù) 有符號半字 放入Rd中LDR cond HRd 加載半字數(shù)據(jù) 放入Rd中 即Rd最低16位有效 高16位清零STR cond HRd 存儲半字數(shù)據(jù) 要存儲的數(shù)據(jù)在Rd 最16位有效這類LDR STR指令可加載有符號字節(jié) 加載有符號半字以及加載 存儲無符號半字 偏移量格式 尋址方式與加載 存儲字和無符號字節(jié)指令相同 3 2 1 3ARM存儲器訪問指令 10 說明 有符號位半字 字節(jié)加載是指用符號位擴展到32位 無符號位半字加載是指零擴展到32位 地址對齊 對半字傳送的地址必須是偶數(shù) 非半字對齊的半字加載將使Rd內容不可靠 非半字對齊的半字存儲將使指令地址的2字節(jié)存儲內容不可靠 應用示例 LDR STR指令用于對內存變量的訪問 內存緩沖區(qū)數(shù)據(jù)的訪問 查表 外圍部件的控制操作等 若使用LDR指令加載數(shù)據(jù)到PC寄存器 則實現(xiàn)程序跳轉功能 這樣也就實現(xiàn)了程序散轉 3 2 1 3ARM存儲器訪問指令 11 LDR指令在異常向量表中的散轉應用 在第2章中了解到每個異常都有自己的入口地址 那么在這些入口地址上放置的跳轉指令所組成的一段代碼 稱之為異常向量表 異常向量表的作用就是讓處理器在發(fā)生異常時能順利地找到對應的服務程序 而異常向量表就是使用了LDR指令來實現(xiàn)程序散轉的 異常向量表的部分代碼如程序清單3 2所示 通過觀察LDR指令可以發(fā)現(xiàn) 它們使用的是 程序相對偏移 尋址方式 比如 復位異常入口處的指令 LDRPC ResetAddr 它是將程序標號ResetAddr地址處存放的數(shù)據(jù)讀取到PC寄存器中 該地址上存放的是程序標號ResetInit 它是復位異常服務程序的地址 因此一旦發(fā)生復位 處理器執(zhí)行復位異常入口處的指令 便可實現(xiàn)向復位服務程序的跳轉動作 更詳細的過程將在后續(xù)的內容中陸續(xù)介紹 3 2 1 3ARM存儲器訪問指令 12 程序清單3 2LDR用于異常向量表實現(xiàn)程序散轉 3 2 1 3ARM存儲器訪問指令 13 LDR STR指令在變量操作中的應用 在使用C語言時長定義一些全局變量 編譯器通常會將全局變量安排存放在存儲器中 所以在訪問該全局變量時就要用到LDR或STR指令 例如 在C語言下要實現(xiàn)兩個全局變量之間的參數(shù)傳遞 只需參見程序清單3 3代碼 程序清單3 3用C語言完成全局變量的參數(shù)傳遞該C代碼被編譯器編譯后便會生成如程序清單3 4所示的匯編代碼 代碼的前兩條LDR指令是偽指令 它用于將一個常數(shù)存放到寄存器中 LDR偽指令的詳細介紹參看 3 2 1 3ARM存儲器訪問指令 14 本小節(jié)的 ARM偽指令 它們在本程序中的用途是將全局變量OSPrioCur和OSPrioHighRdy的地址分別存放到R4和R5中 見圖3 4 在獲取到變量的地址后 第 句程序使用LDRB指令把OSPrioHighRdy變量的內容取出 該指令的B后綴使它只讀取1字節(jié)數(shù)據(jù) 在第 句程序中 使用STRB指令把獲取到的OSPrioHighRdy變量內容寫入到OSPrioCur變量中 整個代碼的執(zhí)行過程如程序清單3 4所示 程序清單3 4用LDR和STR指令實現(xiàn)全局變量的訪問 3 2 1 3ARM存儲器訪問指令 15 圖3 4全局變量訪問過程 3 2 1 3ARM存儲器訪問指令 16 2 LDM STM 多寄存器加載 存儲指令 指令格式 LDM cond Rn reglist STM cond Rn reglist 指令功能 多寄存器加載 存儲指令可以實現(xiàn)在一組寄存器和一塊連續(xù)的內存單元之間傳輸數(shù)據(jù) LDM為加載多個寄存器 STM為存儲多個寄存器 允許一條指令傳送16個寄存器的任何子集或所有寄存器 指令說明 LDM和STM的主要用途是現(xiàn)場保護 數(shù)據(jù)復制 參數(shù)傳送等 其指令格式如圖3 5所示 圖3 5中 模式 有如下8種 前面4種用于數(shù)據(jù)塊的傳輸 后面4種是堆棧操作 IA 每次傳送后地址加4 IB 每次傳送前地址加4 DA 每次傳送后地址減4 DB 每次傳送前地址減4 3 2 1 3ARM存儲器訪問指令 17 FD 滿遞減堆棧 ED 空遞減堆棧 FA 滿遞增堆棧 EA 空遞增堆棧 圖3 5LDM和STM指令格式說明 3 2 1 3ARM存儲器訪問指令 18 注意事項 指令格式中的Rn寄存器為基址寄存器 它保存了所要操作存儲單元的起始地址 從該地址開始的一段連續(xù)的地址空間都是要進行讀 寫的存儲單元 Rn不允許為R15 PC Rn的內容是一個指針 在指令執(zhí)行前它指向起始地址 在指令執(zhí)行結束后有兩種選擇 一種是保持Rn的內容前后不變化 其中 Rn無 后綴 如圖3 6 b 所示 另一種是讓Rn指向操作結束的地址 后綴 就是用于該功能的控制 如果加上 后綴 表示最后的地址寫回到Rn中 如圖3 6 c 所示 程序清單3 5帶 后綴的LDM指令 3 2 1 3ARM存儲器訪問指令 19 圖3 6LDM指令執(zhí)行前后寄存器狀態(tài) 3 2 1 3ARM存儲器訪問指令 20 寄存器列表reglist可包含多于一個寄存器或包含寄存器范圍 使用 分開 例如 R1 R2 R6 R9 寄存器就是由小到大排列 寄存器與內存單元的對應關系是 編號低的寄存器對應于內存中低地址單元 標號高的寄存器對應于內存中的高地址單元 后綴不允許在用戶模式或系統(tǒng)模式下使用 若在LDM指令且寄存器列表中包含有PC時使用 那么除了正常的多寄存器傳送外 還會把SPSR也復制到CPSR中 這可用于異常處理返回 使用 后綴進行數(shù)據(jù)傳送且寄存器列表不包含PC時 則加載 存儲的是用戶模式的寄存器 而不是當前模式的寄存器 地址對齊 這些指令忽略地址的位 1 0 3 2 1 3ARM存儲器訪問指令 21 應用示例 在進行數(shù)據(jù)復制時 先設置好源數(shù)據(jù)指針和目標指針 然后使用塊復制尋址指令LDMIA STMIA LDMIB STMIB LDMDA STMDA LDMDB STMDB進行讀取和存儲 進行堆棧操作時 要先設置堆棧指針 一般使用SP 然后使用堆棧尋址指令STMFD LDMFD STMED LDMED STMFA LDMFA和STMEA LDMEA實現(xiàn)堆棧操作 說明 上面提到的數(shù)據(jù)復制和堆棧操作的4種方式是可以互用的 比如 在使用STMFD時也可以使用LDMDB來替代 3 2 1 3ARM存儲器訪問指令 22 多寄存器傳送指令示意圖如圖3 7所示 其中R1為指令執(zhí)行前的基址寄存器 R1 則為指令執(zhí)行完后的基址寄存器 圖3 7多寄存器傳送指令示意圖 3 2 1 3ARM存儲器訪問指令 23 使用多寄存器傳送指令時 基址寄存器的地址是向上增長還是向下增長 地址是在加載 存儲數(shù)據(jù)之前還是之后增加 減少 其對應關系如表3 3所列 表3 3多寄存器傳送指令映射 3 2 1 3ARM存儲器訪問指令 24 因為在實際應用中通常使用C語言進行程序編寫 所以此時的堆棧形式與編譯器有關 對于ADS工具自帶的C編譯器使用的是 滿遞減 的堆棧形式 如程序清單3 6所示 該指令是將寄存器R0 R7保存到堆棧之中 指令執(zhí)行前后的寄存器和存儲器內容變化如圖3 8所示 通過仔細觀察可以發(fā)現(xiàn) 堆棧指針SP寄存器所指向的存儲器始終是保存有堆棧數(shù)據(jù)的 程序清單3 6滿遞減堆棧的壓棧操作 3 2 1 3ARM存儲器訪問指令 25 圖3 8使用STM壓棧指令的前后對比 3 2 1 3ARM存儲器訪問指令 26 與壓棧操作相對應的出棧操作是通過LDM指令來實現(xiàn)的 需要特別注意 為了讓堆棧指針能正確移動 出棧和壓棧時的LDM指令的后綴必須都是一致的 比如程序清單3 6中使用的FD后綴 那么出棧時也同樣要使用FD后綴 如程序清單3 7和程序清單3 8所示 因為出棧操作常發(fā)生在函數(shù)返回時 所以通常在出棧的同時將之前入棧的LR寄存器內容恢復到PC寄存器中 實現(xiàn)程序的返回 程序清單3 7使用LDM指令出棧程序清單3 8使用LDM指令出棧并恢復CPSR寄存器 3 2 1 3ARM存儲器訪問指令 27 仔細觀察程序清單3 7和程序清單3 8會發(fā)現(xiàn) 后者的指令上多了一個 符號 這個符號的功能是 如果操作寄存器組中存在PC寄存器 那么在恢復寄存器的同時將當前模式下的SPSR寄存器內容恢復到CPSR寄存器中 因此 程序清單3 7常用于子程序調用的出棧返回 而程序清單3 8常用于中斷服務程序的出棧返回 它們的使用效果如圖3 9所示 3 2 1 3ARM存儲器訪問指令 28 圖3 9使用LDM指令出棧操作 3 2 1 3ARM存儲器訪問指令 29 3 SWP 寄存器和存儲器交換指令 指令格式 SWP cond B Rd Rm Rn 指令功能 SWP指令用于將一個內存單元 該單元地址放在寄存器Rn中 的內容讀取到一個寄存器Rd中 同時將另一個寄存器Rm的內容寫入到該內存單元中 使用SWP可實現(xiàn)信號量操作 其中 B為可選后綴 若有B 則交換字節(jié) 否則交換32位字 Rd為數(shù)據(jù)從存儲器讀出后的目標保存寄存器 Rm的數(shù)據(jù)存儲到存儲器中 若Rm與Rn相同 則寄存器與存儲器內容進行交換 Rn為要進行數(shù)據(jù)交換的存儲器地址 Rn不能與Rd和Rm相同 3 2 1 3ARM存儲器訪問指令 30 應用示例 3 2 1 4ARM數(shù)據(jù)處理指令 1 數(shù)據(jù)處理指令大致可分為3類 數(shù)據(jù)傳送指令 如MOV MVN 算術邏輯運算指令 如ADD SUB AND 和比較指令 如CMP TST 見表3 4 其用法比較簡單 數(shù)據(jù)處理指令只能對寄存器的內容進行操作 所有ARM數(shù)據(jù)處理指令均可選擇使用S后綴 并影響狀態(tài)標志 比較指令CMP CMN TST和TEQ不需要后綴S 它們會直接影響狀態(tài)標志 3 2 1 4ARM數(shù)據(jù)處理指令 2 表3 4ARM數(shù)據(jù)處理指令 3 2 1 4ARM數(shù)據(jù)處理指令 3 CMP指令將寄存器Rn的值減去operand2的值 根據(jù)操作的結果更新CPSR中的相應條件標志位 以便后面的指令根據(jù)相應的條件標志來判斷是否執(zhí)行 指令格式 CMP cond Rn operand2應用示例 CMP指令與SUBS指令的區(qū)別在于CMP指令不保存運算結果 在進行兩個數(shù)據(jù)的大小判斷時 常用CMP指令及相應的條件碼來操作 程序清單3 9為使用CMP指令實現(xiàn)傳入?yún)?shù)的匹配操作 3 2 1 4ARM數(shù)據(jù)處理指令 4 程序清單3 9使用CMP指令實現(xiàn)數(shù)據(jù)比較 3 2 1 5乘法指令 ARM9TDMI S 具有32 32乘法指令 32 32乘加指令 32 32結果為64位的乘 乘加指令 ARM乘法指令見表3 5 由于其用法比較簡單 在此不再作詳細介紹 表3 5ARM乘法指令 3 2 1 6ARM分支指令 1 在ARM中有兩種方式可以實現(xiàn)程序的跳轉 一種是使用分支指令直接跳轉 另一種則是直接向PC寄存器賦值實現(xiàn)跳轉 分支指令有分支指令B 帶鏈接的分支指令BL 帶狀態(tài)切換的分支指令BX 見表3 6 由于其用法比較簡單 在此不再做詳細介紹 表3 6ARM分支指令 3 2 1 6ARM分支指令 2 1 B 分支指令 指令格式 B cond label指令編碼格式 signed immed 24 24位有符號立即數(shù) 偏移量 L 區(qū)別分支 L為0 或帶鏈接的分支指令 L為1 指令功能 B指令跳轉到指定的地址去執(zhí)行程序 3 2 1 6ARM分支指令 3 應用示例 3 2 1 6ARM分支指令 4 2 BL 帶鏈接的分支指令 指令格式 BL cond label指令編碼格式 signed immed 24 24位有符號立即數(shù) 偏移量 L 區(qū)別分支 L為0 或帶鏈接的分支指令 L為1 指令功能 BL指令將下一條指令的地址復制到R14 即LR 鏈接寄存器中 然后跳轉到指令地址 運行程序 3 2 1 6ARM分支指令 5 應用示例 帶鏈接的分支指令BL限制在當前指令的 32MB地址范圍內 BL指令用于子程序調用 3 2 1 6ARM分支指令 6 3 BX 帶狀態(tài)切換的分支指令 指令格式 BX cond Rm指令編碼格式 Rm 目標地址寄存器 指令功能 BX指令跳轉到Rm指定的地址去執(zhí)行程序 若Rm的bit0為1 則跳轉時自動將CPSR中的標志位T置位 即把目標地址的代碼解釋為Thumb代碼 若Rm的bit0為0 則跳轉時自動將CPSR中的標志位T復位 即把目標地址的代碼解釋為ARM代碼 3 2 1 6ARM分支指令 7 應用示例 3 2 1 7ARM雜項指令 1 ARM雜項指令見表3 7 表3 7ARM雜項指令 3 2 1 7ARM雜項指令 2 1 SWI 軟件中斷指令 指令格式 SWI cond immed 24指令編碼格式 Immed 24 24位立即數(shù) 為0 16777215之間的整數(shù) 常被用于參數(shù)傳遞 指令功能 SWI指令用于用于產(chǎn)生軟件中斷 從而實現(xiàn)從用戶模式到管理模式的變換 請參看第2章相關內容 在切換時 CPSR寄存器內容將保存到管理模式的SPSR中 同時程序跳轉到SWI異常向量入口處 在其他模式下也可使用SWI指令 處理器同樣會切換到管理模式 3 2 1 7ARM雜項指令 3 應用示例 在2 7 10小節(jié)中 SWI常用于系統(tǒng)功能調用 在軟件中斷服務程序中根據(jù)程序傳遞的功能號來執(zhí)行對應的服務程序 因此在使用軟件中斷時 功能號的傳遞和處理是一個很重要的步驟 通常使用以下兩種方法進行功能號的傳遞 這兩種方法均由用戶軟件協(xié)定 指令中24位立即數(shù)指令了用戶請求的服務類型 參數(shù)通過通用寄存器傳遞 SWI異常中斷處理程序要通過讀取引起軟件中斷的SWI指令 以取得24位立即數(shù) 3 2 1 7ARM雜項指令 4 指令中的24位立即數(shù)被忽略 用戶請求的服務類型由寄存器R0的值決定 參數(shù)通過其他寄存器傳遞 在SWI異常中斷處理程序中 讀取SWI立即數(shù)的步驟為 首先 確定引起軟件中斷的SWI指令是ARM指令還是Thumb指令 這可通過對SPSR訪問得到 然后 取得該SWI指令的地址 這可通過訪問LR寄存器得到 最后 讀出指令 分解出立即數(shù) 如程序清單3 10所示 3 2 1 7ARM雜項指令 5 程序清單3 10讀取SWI立即數(shù) 3 2 1 7ARM雜項指令 6 2 MRS 讀狀態(tài)寄存器指令 指令格式 MRS cond Rd psr其中 Rd為目標寄存器 Rd不允許為R15 psr為CPSR或SPSR 指令功能 在ARM處理器中 只有MRS指令可以將狀態(tài)寄存器CPSR或SPSR讀出到通用寄存器中 應用示例 3 2 1 7ARM雜項指令 7 MRS指令讀取CPSR 可用來判斷ALU的狀態(tài)標志 或IRQ FIQ中斷是否使能等 在異常處理程序中 讀SPSR可知道進行異常前的處理器狀態(tài)等 MRS與MSR配合使用 實現(xiàn)CPSR或SPSR寄存器的讀 修改 寫操作 可用來進行處理器模式切換 使能 禁止IRQ FIQ中斷等設置 如程序清單3 11 程序清單3 12所示 另外 進程切換或使能異常中斷嵌套時 也需要使用MRS指令讀取SPSR狀態(tài)值 并保存起來 程序清單3 11使能IRQ中斷 3 2 1 7ARM雜項指令 8 程序清單3 12禁止IRQ中斷 3 2 1 7ARM雜項指令 9 3 MSR 寫狀態(tài)寄存器指令 指令格式 MSR cond psr fields immed 8rMSR cond psr fields Rm其中 psr為CPSR或SPSR fields為指定傳送的區(qū)域 fields可以是以下的一種或多種 字母必須為小寫 c 控制域屏蔽字節(jié) psr 7 0 x 擴展域屏蔽字節(jié) psr 15 8 s 狀態(tài)域屏蔽字節(jié) psr 23 16 f 標志域屏蔽字節(jié) psr 31 24 各個域在CPSR寄存器中的位置如圖3 10所示 3 2 1 7ARM雜項指令 10 圖3 10程序狀態(tài)寄存器的域的位置immed 8r為要傳送到狀態(tài)寄存器指定域的8位立即數(shù) Rm為要傳送到狀態(tài)寄存器指定域的數(shù)據(jù)的源寄存器 指令功能 在ARM處理器中 只有MSR指令可以直接設置狀態(tài)寄存器CPSR或SPSR 3 2 1 7ARM雜項指令 11 應用示例 注意 只有在特權模式下才能修改狀態(tài)寄存器 程序中不能通過MSR指令直接修改CPSR中的T控制位來實現(xiàn)ARM狀態(tài) Thumb狀態(tài)的切換 必須使用BX指令完成處理器狀態(tài)的切換 因為BX指令屬分支指令 它會打斷流水線狀態(tài) 實現(xiàn)處理器狀態(tài)切換 MRS與MSR配合使用 實現(xiàn)CPSR或SPSR寄存器的讀 修改 寫操作 可用來進行處理器模式切換 使能 禁止IRQ FIQ中斷等設置 如程序清單3 13所示 3 2 1 7ARM雜項指令 12 程序清單3 13堆棧指令初始化程序清單3 13中 MSRCPSR c 0Xd3 指令的操作結果入圖3 11所示 3 2 1 7ARM雜項指令 13 圖3 11向CPSR控制域寫操作的結果 3 2 1 8ARM偽指令 1 ARM偽指令不是ARM指令集中的指令 只是為了編程方便 編譯器定義了偽指令 使用時可以像其他ARM指令一樣使用 但在編譯時這些指令將被等效的ARM指令代替 ARM常用的偽指令有4條 分別為ADR偽指令 ADRL偽指令 LDR偽指令 NOP偽指令 1 ADR 小范圍的地址讀取偽指令 指令格式 ADR cond register expr其中 register為加載的目標寄存器 expr為地址表達式 當?shù)刂分凳欠亲謱R時 取值范圍為 255 255字節(jié) 當?shù)刂分凳亲謱R時 取值范圍為 1020 1020字節(jié) 對于基于PC相對偏移的地址值時 給定范圍是相對當前指令地址后兩個字處 因為ARM9TDMI的流水線特性 3 2 1 8ARM偽指令 2 指令功能 ADR指令將基于PC相對偏移的地址值或基于寄存器相對偏移的地址值讀取到寄存器中 在匯編編譯源程序時 ADR偽指令被編譯器替換成一條合適的指令 通常 編譯器用一條ADD指令或SUB指令來實現(xiàn)該ADR偽指令的功能 若不能用一條指令實現(xiàn) 則產(chǎn)生錯誤 應用示例 可以用ADR加載地址 實現(xiàn)查表 如程序清單3 14所示 3 2 1 8ARM偽指令 3 程序清單3 14小范圍地址的加載 3 2 1 8ARM偽指令 4 2 ADRL 中等范圍的地址讀取偽指令 指令格式 ADRL cond register expr其中 register為加載的目標寄存器 expr為地址表達式 當?shù)刂分凳欠亲謱R時 取值范圍為 64 64KB 當?shù)刂分凳亲謱R時 取值范圍為 256 256KB 對于基于PC相對偏移的地址值時 給定范圍是相對當前指令地址后兩個字處 因為ARM9TDMI的流水線特性 3 2 1 8ARM偽指令 5 指令功能 ADR指令將基于PC相對偏移的地址值或基于寄存器相對偏移的地址值讀取到寄存器中 比ADR偽指令讀取更大的地址范圍 在匯編編譯源程序時 ADRL偽指令被編譯器替換成兩條合適的指令 若不能用兩條指令實現(xiàn)ADRL偽指令功能 則產(chǎn)生錯誤 編譯失敗 應用示例 3 2 1 8ARM偽指令 6 可以用ADRL加載地址 實現(xiàn)程序跳轉 如程序清單3 15所示 程序清單3 15中等范圍地址的加載 3 2 1 8ARM偽指令 7 3 LDR 大范圍的地址讀取偽指令 指令格式 LDR cond register expr label expr其中 register為加載的目標寄存器 expr為32位立即數(shù) label expr是基于PC的地址表達式或外部表達式 指令功能 LDR偽指令用于加載32位的立即數(shù)或一個地址值到指定寄存器 在匯編編譯源程序時 LDR偽指令被編譯器替換成一條合適的指令 若加載的常數(shù)未超過MOV或MVN的范圍 則使用MOV或MVN指令代替該LDR偽指令 否則匯編器將常量放入文字池 并使用一條程序相對偏移的LDR加載指令從文字池讀出常量 3 2 1 8ARM偽指令 8 應用示例 偽指令LDR常用于加載芯片外圍功能部件的寄存器 32位立即數(shù) 以實現(xiàn)各種控制操作 如程序清單3 16所示 3 2 1 8ARM偽指令 9 程序清單3 16加載32位立即數(shù)從PC到文字池的偏移量必須小于4KB 與ARM指令的LDR相比 偽指令的LDR的參數(shù)有 號 說明 若沒有使用LTORG聲明文字池 則匯編器會在程序末尾自動聲明 3 2 1 8ARM偽指令 10 4 NOP 空操作偽指令 指令格式 NOP指令功能 NOP偽指令在匯編時會被代替成ARM中的空操作 比如可能為 MOVR0 R0 指令等 NOP可用于延時操作 如程序清單3 17所示 程序清單3 17軟件延時 3 2 2Thumb指令集 Thumb指令集可以看作是ARM指令壓縮形式的子集 是針對代碼密度的問題而提出的 它具有16位的代碼密度 Thumb不是一個完整的體系結構 不能指望處理器只執(zhí)行Thumb指令而不支持ARM指令集 因此 Thumb指令只需要支持通用功能 必要時可以借助完善的ARM指令集 比如 所有異常自動進入ARM狀態(tài) 在編寫Thumb指令時 先要使用偽指令CODE16聲明 但是在ARM指令中要使用BX指令跳轉到Thumb指令 以切換處理器狀態(tài) 編寫ARM指令時 則可使用偽指令CODE32聲明 由ARM狀態(tài)切換到Thumb狀態(tài)的代碼 如程序清單3 18所示 程序清單3 18ARM到Thumb的狀態(tài)切換 程序首先在ARM狀態(tài)下使用 ADRR0 THUMB CODE 1 偽指令裝載THUMB CODE的地址 為了使R0的bit0為1 所以使用了 THUMB CODE 1 這樣使用BX即可把處理器狀態(tài)切換到Thumb狀態(tài) 所有ARM指令都是可以有條件執(zhí)行的 而Thumb指令僅有一條指令 分支指令B 具備條件執(zhí)行功能 ARM程序和Thumb程序可相互調用 相互之間的狀態(tài)切換幾乎為零 本章對Thumb指令僅做簡要介紹 3 2 2 1Thumb與ARM指令集的區(qū)別 1 Thumb指令集沒有協(xié)處理器指令 信號量指令以及訪問CPSR或SPSR的指令 沒有乘加指令及64位乘法指令等 并且指令的第二操作數(shù)受到限制 除了分支指令B有條件執(zhí)行功能外 其他指令均為無條件執(zhí)行 大多數(shù)Thumb數(shù)據(jù)處理指令采用2地址格式 Thumb指令集與ARM指令集的區(qū)別一般有如下4點 分支指令 程序相對轉移 特別是條件跳轉與ARM代碼下的跳轉相比 在范圍上有更多的限制 轉向子程序是無條件的轉移 數(shù)據(jù)處理指令 數(shù)據(jù)處理指令是對通用寄存器進行操作 在大多數(shù)情況下 操作的結果須放入其中一個操作數(shù)寄存器中 而不是第3個寄存器中 數(shù)據(jù)處理操作比ARM狀態(tài)的更少 訪問R8 R15受到一定限制 除MOV和ADD指令訪問寄存器R8 R15外 其他數(shù)據(jù)處理指令總是更新CPSR中的ALU狀態(tài)標志 訪問寄存器R8 3 2 2 1Thumb與ARM指令集的區(qū)別 2 R15的Thumb數(shù)據(jù)處理指令不能更新CPSR中的ALU狀態(tài)標志 單寄存器加載和存儲指令 在Thumb狀態(tài)下 單寄存器加載和存儲指令只能訪問寄存器R0 R7 多寄存器加載和多寄存器存儲指令 LDM和STM指令可以將任何范圍為R0 R7的寄存器子集加載或存儲 PUSH和POP指令使用堆棧指針R13作為基址實現(xiàn)滿遞減堆棧 除R0 R7外 PUSH指令還可以存儲鏈接寄存器R14 并且POP指令可以加載程序計數(shù)器PC 3 2 2 2Thumb存儲器訪問指令 1 Thumb指令集的LDM和STM指令可以將任何范圍為R0 R7的寄存器子集加載或存儲 多寄存器加載和多寄存器存儲指令只有LDMIA STMIA指令 即每次傳送先加載數(shù)據(jù) 然后地址加4 對堆棧處理只能使用PUSH及POP指令 Thumb存儲器訪問指令見表3 8 Thumb存儲器訪問指令中 STR LDR STM LDM的使用方法與ARM指令集中相對應的指令類似 不再詳細介紹 3 2 2 2Thumb存儲器訪問指令 2 表3 8Thumb存儲器訪問指令 3 2 2 3Thumb數(shù)據(jù)處理指令 1 大多
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 公共領域車輛全面電動化實施方案
- 小說人物塑造的技巧和方法教案
- 一轉身我已不再年輕12篇
- 我心兒怦怦跳作文400字13篇
- 社區(qū)林業(yè)資源經(jīng)營管理責任書
- 上海建平中學高一(下)期末物理試題及答案
- 專業(yè)工作經(jīng)歷與崗位證明書(7篇)
- 寫人作文游戲控老爸600字13篇
- 心愛物品的往事回憶作文(8篇)
- 壁虎的啟示350字10篇
- 音樂與藝術在全球中的多樣性與融合
- 基于項目驅動的創(chuàng)新實踐課程設計
- 2025電子產(chǎn)品供銷合同
- 2025中考英語閱讀考點專項突破訓練:旅游(學生版+解析)
- 安全月考試試題及答案
- 專利培訓試題及答案
- 國際工程投標管理制度
- 2025河南濮陽市南樂縣紀委監(jiān)委招聘編外看護隊員筆試易考易錯模擬試題(共500題)試卷后附參考答案
- java高級程序員面試題及答案
- T/BCEA 003-2022數(shù)字工程裝配式混凝土結構智慧工地建設導則
- 納米技術在靶向藥物delivery中的創(chuàng)新應用-洞察闡釋
評論
0/150
提交評論