ARM彙編程序設計學習筆記(一)

ARM彙編程序設計學習筆記(一)

爲了學習android系統,發現需要學習linux驅動,發現學習linux驅動,需要先知道處理器的各種架構,爲了學習此種知識,發現網上有很多mini2440相關的知識,因此,將其作爲藍本,認真學習。直到linux驅動的學習完成。

這是linux驅動學習的第一部分,arm的彙編程序。

本文檔的大部分資料翻譯於《S3C2440A 32-BIT CMOS MICROCONTROLLER USER’S MANUAL》

一.編程模型

處理器工作狀態

從程序員的角度來看,ARM920T(s3c2440的內核)有如下兩種狀態:

  1. ARM狀態,執行32位,字對齊的指令
  2. THUMB狀態,執行16位,半字對齊的THUMB指令。

注意:這兩種狀態的切換,不會影響處理器的模式和寄存器狀態

1.1 切換狀態

進入THUMB狀態

將操作數寄存器的第0位,設爲1,然後執行BX指令,就可以切換爲THUMB狀態。

例如:

BX Rm;如果Rm的第0位,是1,則跳轉到Rm所在的地址,並且設置處理器在thumb模式下

如果在THUMB狀態下,進入了異常,從異常中退出,依然是THUMB狀態

進入ARM狀態

可以通過下面的方法,進入arm狀態:

  1. 將操作數寄存器的第0位,清零,然後執行BX指令
BX Rm;如果Rm的第0位,是0,則跳轉到Rm所在的地址,並且設置處理器爲arm模式下
  1. 處理器發生異常時,PC被放置在異常模式下的連接寄存器中,然後從異常向量地址開始執行

1.2 內存格式

ARM920T 將內存視爲一個線性的字節序列。字節地址從0開始。0到3字節保存第一個字。4到7字節保存第二個字,依次類推。這些字支持小端和大端格式。

1.3 指令長度

指令長度爲32位長(arm模式)和16位長(thumb模式)

1.4 數據類型

ARM920T 支持字節(8位)、半字(16位)、字(32位)數據類型。字必須4字節對齊。半字必須兩字節對齊。

1.5 運行模式

ARM920T 支持7種運行模式:

  1. User(usr):最普通的arm執行狀態
  2. FIQ(fiq):被用來進行數據傳輸,和信道處理
  3. IRQ(irq):通用的中斷處理
  4. Supervisor(svc):爲操作系統設計的保護模式
  5. Abort mode(abt):數據和指令預取發生問題時,進入
  6. System(sys):爲操作系統設計的特權用戶模式
  7. Undefined(und):當一個未定義的指令執行時,進入此模式

模式的改變可以通過軟件控制,也可以通過外部的中斷,或者異常。大多數的應用程序將運行在用戶模式下。

特殊模式(非用戶模式)僅僅在服務中斷或者異常,或者訪問受保護的資源時纔會進入。

1.6 寄存器

ARM920T 總共有37個寄存器。其中,31個通用的32位寄存器和6個狀態寄存器。這37個寄存器,對於程序來說,不能同時可見。

處理器狀態和運行模式,決定了那些寄存器對於程序員來說可見。

1.7 arm狀態下的寄存器集

在arm狀態下,程序員只能看到16個通用寄存器和1個或者2個狀態寄存器。在特殊模式(非用戶模式),相應的寄存器組被切換。圖2-3展示了在每種模式下那些寄存器可見。這些寄存器組使用一個陰影三角形標記:

在這裏插入圖片描述

arm狀態下的寄存器組包含16個可直接訪問的寄存器:R0-R15.除了R15寄存器以外,其他的寄存器都是通用寄存器。可以用來存儲數據或者地址。

除此之外,還有第十七個寄存器用來存儲狀態信息。

寄存器 描述
寄存器14 該寄存器作爲子程序的鏈接寄存器。當分支指令(Branch)和連接指令(BL)執行時,這個寄存器保存R15的值.其他時候,可以被作爲通用寄存器來使用。對應的寄存器有:R14_svc,R14_irq,R14_fiq,R14_abt,R14_und,他們都在對應的模式下保存R15的值
寄存器15 這個寄存器爲程序計數器(PC)。在arm模式下,bits[1:0]是0,bits[31-2]保存PC。在thumb模式下,bit[0]爲0,bits[31:1]保存PC
寄存器16 這個寄存器是CPSR(當前程序狀態寄存器)。它保存代碼的各種flag和一些模式位

FIQ模式有7個寄存器,被映射爲R8-R14(R8_fiq-R14_fiq).在arm模式下有許多FIQ處理程序不需要保存的寄存器。

而USer,IRQ,SuperVisor,Abort和Undefined模式,都有R13和R14,並且允許他們有自己的堆棧指針和鏈接寄存器

ARM和THUMB之間的寄存器關係

如下:

  1. THUMB模式下R0-R7 ,ARM模式下R0-R7 完全相同
  2. THUMB模式下CPSR和SPSRs,ARM模式下CPSR和SPSRs是完全相同的
  3. THUMB模式下SP映射爲ARM的R13
  4. THUMB模式下LR映射爲ARM下的R14
  5. THUMB模式下PC映射爲ARM的R15

在這裏插入圖片描述

在thumb模式下訪問高寄存器組(Hi-registers)

在THUMB模式下,寄存器組R8-R15(被稱爲Hi-registers)不是標準寄存器組中的一部分。因此,彙編程序對他的訪問是受限制的。但是他們可以用來作爲臨時的存放地。

可以使用mov指令,將R0-R7裏面的值放置到高寄存器中。也可以將高寄存器中的值放到低寄存器中(R0-R7)

也可以使用CMP指令,將高寄存器和低寄存器進行比較

也可以使用ADD指令,將高寄存器中的值加到低寄存器中

1.8 程序狀態寄存器

ARM920T 包含一個當前程序狀態寄存器(CPSR),以及5個已經保存了的程序狀態寄存器(SPSR)。這些寄存器的功能有:

  1. 保存執行單元(ALU)最近的信息
  2. 打開或者關閉中斷
  3. 處理器運行模式
31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
N Z C V - - - - - - - - - - - - - - - - - - - - I F T M4 M3 M2 M1 M0

條件碼標識

N,Z,C,V是條件碼的標誌位。這些將會被算術和邏輯運算改變,然後再根據這些位來決定指令是否執行。

在arm狀態下,所有的指令可以被條件的執行。

在thumb狀態下,只有分支指令纔可以按照條件執行

控制位

最低下的8位被稱爲控制位。當一個異常發生時,他們會被改變。如果處理器在特權模式下,那麼他們也可以被軟件手動改變。

描述
T 當爲1時,處理器運行在THUMB模式下,否則運行在ARM模式下。他將影響TBIT外部信號
中斷禁止位 I和F是中斷禁止位。爲1,則相應的禁止IRQ和FIQ
模式位 M4,M3,M2,M1,M0是模式位,如下表,只有下表出現的模式纔是正確的模式,一旦程序設置了錯誤的模式,則會產生復位異常
保留位 剩下的位爲保留位。
M[4:0] 模式 thumb模式下的寄存器 arm模式下的寄存器
10000 User R7…R0,LR,SP,PC,CPSR R14…R0,PC,CPSR
10001 FIQ R7…R0,LR_fiq,SP_fiq,PC,CPSR,SPSR_fiq R7…R0,R14_fiq…R8_fiq,PC,CPSR,SPSR_fiq
10010 IRQ R7…R0,LR_irq,SP_irq,PC,CPSR,SPSR_irq R12…R0,R14_irq,R13_irq,PC,CPSR,SPSR_iraq
10011 Supervisor R7…R0,LR_svc,SP_svc,PC,CPSR,SPSR_svc R12…R0,R14_svc,R13_svc,PC,CPSR,SPSR_svc
10111 Abort R7…R0,LR_abt,SP_abt,PC,CPSR,SPSR_abt R12…R0,R14_abt,R13_abt,PC,CPSR,SPSR_abt
11011 Undefined R7…R0,LR_und,SP_und,PC,CPSR,SPSR_und P12…R0,R14_und,R13_und,PC,CPSR
11111 System R7…R0,LR,SP,PC,CPSR R14…R0,PC,CPSR

1.9 異常

例如響應外設電路的中斷,此時反生異常。在異常處理前,當前處理器的狀態必須保存下來,目的是,當異常處理完成之後,可以繼續執行

在同一時間,可能同時出現多個異常,此時他們以固定的順序進行處理,詳見下面的異常優先級。

進入異常時的操作

當處理異常時,ARM920T會做如下的操作:

  1. 在鏈接寄存器中保存下一個指令的地址。如果異常從arm狀態進入,則下一個指令的地址被複制到鏈接寄存器中(即PC+4,或者PC+8,具體依賴於不同的異常,後面有詳細說明)如果異常從THUMB狀態進入,鏈接寄存器則保存當前PC的偏移量。這就意味着,異常處理程序,不用管,到底是從哪個狀態進入的異常。
  2. 賦值CPSR到對應的SPSR
  3. 修改CPSR對應的模式位
  4. 修改PC爲對應的異常向量地址

還可以設置異常禁止位,防止異常嵌套的發生

如果處理器在THUMB狀態下,此時發生了異常,當PC指向異常向量的地址時,自動切爲ARM狀態

離開異常時的操作

異常處理程序完成後:

  1. 將鏈接寄存器的值,複製到PC中
  2. 複製SPSR到CPSR
  3. 如果允許中斷,則清除中斷禁止位,

異常入口/出口摘要

下表列出了異常發生時,保存在鏈接寄存器中的PC的值,以及退出異常處理程序的推薦的指令

返回的指令 arm R14_x thumb R14_x
BL;MOV PC,R14 PC+4 PC+2
SWI;MOVS PC,R14_svc PC+4 PC+2
UDEF;MOVS PC,R14_und PC+4 PC+2
FIQ;SUBS PC,R14_fiq,#4 PC+4 PC+4
IRQ;SUBS PC,R14_irq,#4 PC+4 PC+4
PABT;SUBS PC,R14_abt,#4 PC+4 PC+4
DABT;SUBS PC,R14_abt,#8 PC+8 PC+8
RESET;NA - -

FIQ

FIQ(快速中斷異常)被設計來處理數據傳輸和信道處理。在arm模式下,保證有最小,且足夠的寄存器可用,以達到最優的上下文切換

外部的nFIQ輸入爲低時,產生FIQ異常。根據ISYNC輸入信號的狀態,nFIQ的輸入可以被處理爲同步或異步。當ISYNC爲低時,nFIQ和nIRQ被當做異步。同步的週期延遲發生在中斷影響處理器流之前。

無論異常是從ARM狀態還是thumb狀態進入的,FIQ異常可以通過下面的指令退出異常處理流程:

SUBS PC,R14_fiq,#4

FIQ可以通過CPSR的F位來禁止(用戶模式下無法操作)。如果F位爲0,ARM920T在每條指令結束時檢查FIQ同步器輸出的低電平。

IRQ

IRQ就是常見的中斷,它由nIRQ輸入觸發。IRQ的優先級比FIQ的優先級低並且當FIQ進入時,IRQ將被禁止。通過設置CPSR寄存器的I位,可以在任何時候在特殊模式下(非用戶模式)禁止這個異常

可以執行下面的代碼,返回異常:

SUBS PC,R14_irq,#4

Abort

當前內存訪問無法完成時,產生一個Abort異常。它也可以由外部的ABORT輸入產生。ARM920T在內存訪問週期中,檢查abort異常

兩種abort異常:

  1. 預取址Abort:在指令預取址的時候發生
  2. 數據Abort:數據訪問時發生

如果預取址Abort發生,則取到的指令被標記爲非法指令,並且直到指令到達管道的頭部才發生異常。

如果指令沒有被執行,abort也不會產生,比如分支指令

如果數據abort發生,接下來會發生什麼,則依賴於指令的類型:

  1. 但數據傳輸指令(LDR,STR)寫會被修改的寄存器。abort異常處理程序必須清楚這一點
  2. 交換指令(swap)中止,就好像它沒有被執行一樣
  3. 塊數據傳輸指令繼續完成(LDM,STM)。如果回寫位被置位,則基址寄存器被更新。如果指令要覆蓋基址寄存器,則覆蓋會被中止,以保證不會覆蓋。一旦發生abort異常,所有的寄存器覆蓋都會被中止。因此R15就會被保留

abort機制可以實現按需分頁的虛擬內存系統。在這個系統中,處理器可以產生任意的地址。當數據地址無效時,內存管理單元(MMU)產生一個abort異常。然後abort異常處理程序找出abort的原因,讓請求的數據可用,然後重新執行產生abort異常的指令。

應用程序不需要知道他可用的內存量,他的狀態也不會受abort異常的任何影響

退出abort異常的指令爲:

SUBS PC,R14_abt,#4;for a prefetch abort
SUBS PC,R14_abt,#8;for a data abort

然後恢復PC和CPSR,並且再次執行產生abort異常的指令

軟件中斷

軟件中斷(SWI)被用來進入Supervisor模式。軟件中斷通過下面的指令返回:

MOV PC,R14_svc

他們恢復PC和CPSR,然後繼續執行SWI後面的指令

未定義指令

當arm920T無法處理一個指令時,產生一個未定義指令異常。這種機制可以被用來擴展THUMB和ARM指令的軟件仿真。

可以執行下面的指令,退出異常:

MOVS PC,R14_und

恢復CPSR,然後執行產生未定義指令異常的下一條指令

異常向量表

下表展示了異常向量地址:

地址 異常 進入的模式
0x00000000 Rest Supervisor
0x00000004 Undefined instruction Undefined
0x00000008 Software Interrupt Supervisor
0x0000000C Abort(prefetch) Abort
0x00000010 Abort(data) Abort
0x00000014 Reserved Reserved
0x00000018 IRQ IRQ
0x0000001C FIQ FIQ

異常優先級

當同時產生異常時,系統以固定的順序處理。

高優先級:

  1. Rest
  2. Data abort
  3. FIQ
  4. IRQ
  5. Prefetch abort

低優先級:

  • Undefined instruction,Software Interrupt

注意:並不是所有的異常都能同時發生
未定義指令和軟件中斷異常他們是互斥的

如果數據abort異常和FIQ異常同時發生,並且FIQ異常被允許,ARM920T進入數據abort異常處理程序,然後立刻去處理FIQ的異常。FIQ異常退出之後,繼續在abort異常處理程序中執行。

數據abort的優先級高於FIQ是有道理的,他能夠保證第一時間捕獲到傳輸錯誤。進入這個異常的時間,應該加上FIQ的延遲。

中斷延遲

如果FIQ打開,則最長的延時包括:傳遞給同步器(Tsyncmax)的最長請求時間,加上,最長的指令時間(Tldm),加上,數據abort進入的時間(Texc),加上FIQ進入的時間(Tfiq)。然後纔是ARM920T在0x1c處執行。

Tsyncmax三個處理器週期,Tldm20個處理器週期,Texc3個處理器週期,Tfiq2個處理器週期。總共需要28個處理器週期。在一個連續的20Mhz的處理器上大約消耗1.4微秒。

最大的IRQ延遲計算方式跟上面類似。但是必須考慮到FIQ有更高的優先級,可以延遲任意時間進入IRQ異常處理程序。

FIQ和IRQ的最小時間則由Tsyncmin加上Tfiq組成,爲4個處理器週期。

復位異常

當nREST輸入爲低時,ARM920T放棄執行指令,然後繼續從遞增的字地址中取指令。

當nRest再次變高,ARM920T:

  1. 將當前的PC和CPSR,寫入到R14_svc和SPSR_svc。
  2. 將M[4:0]改爲1011(supervisor模式),CPSR的I,F位置位,清楚CPSR的T位
  3. 將PC爲0x00
  4. 在arm模式下,繼續執行
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章