ARM體系結構與編程筆記

存儲器映射基本概念

ARM處理器產生的地址叫虛擬地址,把這個虛擬地址按照某種規則轉換到另一個物理地址去的方法稱爲地址映射。這個物理地址表示了被訪問的存儲器的位置。它是一個地址範圍,該範圍內可以寫入程序代碼。

存儲器映射控制的必要性

爲了讓運行在不同存儲器空間中的程序對異常進行控制。可以通過存儲器映射控制,將位於不同存儲空間的異常向量表重新映射至固定地址0x00~0x3F處,以實現異常向量表的來源控制。

APCS規定了子程序調用的基本規則,這些規則包括子程序調用過程中寄存器、數據棧的使用規則以及參數的傳遞規則。

異常向量表

對於每一個異常事件,都有一個與之相對應的處理程序,它們是關聯在一起的,並以一張一維表的格式存儲在存儲器的固定單元中。這張指定了各異常中斷及其處理程序的對應關係的表,稱爲異常向量表。

ARM處理器對異常中斷的響應過程

(1)保存處理器當前狀態、中斷屏蔽位以及各條件標誌位。

(2)設置當前程序狀態寄存器CPSR中的相應的位。

(3)將寄存器lr_mode設置成返回地址。

(4)將程序計數器值(PC)設置成該中斷的中斷向量地址,從而跳轉到相應的異常中斷處理程序處執行。

異常的響應過程

除了復位異常外,當異常發生後,ARM核會儘可能執行完當前指令,然後自動執行如下動作:

(1)、保存返回地址到LR_<mode>

(2)、複製CPSR到SPSR_<mode>中。

(3)、設置CPSR進入相應的處理器模式。

(4)、設置CPSR的第7位來禁止IRQ。如果異常爲快速中斷和復位。則還要設置CPSR的第6位來禁止快速中斷。

(5)、給PC強制賦向量地址值。

進入異常

1.在適當的LR中保存下一條指令的地址;2.將CPSR複製到適當的SPSR中;3. 將CPSR模式位強制設置爲與異常類型相對應的值;4.強制PC從相關的異常向量處取指。

退出異常

1.將LR( R14 )中的值減去偏移量後存入PC,偏移量根據異常的類型而有所不同;2.將SPSR的值複製回CPSR;3.清零在入口置位的中斷禁止標誌。

ARM處理器異常分爲①數據中止 ②快速中斷請求③普通中斷請求 ④預取指中止 ⑤軟件中斷 ⑥復位 ⑦未定義指令異常 7種。

異常向量表中程序跳轉使用LDR指令,而沒有使用B指令。原因:

1.LDR指令可以全地址範圍跳轉,而B指令只能在前後32MB範圍內跳轉;

2.芯片具有儲器重新映射(Remap)功能。當向量表位於內部RAM或外部存儲器中,用B指令不能跳轉到正確的位置。

小端存儲器系統:

在小端格式中,高位數字存放在高位字節中。因此存儲器系統字節0連接到數據線7~0(低位對齊)。

大端存儲器系統:

在大端格式中,高位數字存放在低位字節中。因此存儲器系統字節0連接到數據線31~24(高位對齊) 。

STMFD sp!,{lr};保存數據棧LDMFD sp!,{pc};恢復

復位:當nRESET信號再次變爲高電平時,ARM處理器執行下列操作:

1.強制CPSR中的M[4:0]變爲b10011(管理模式);2.置位CPSR中的I和F位;3.清零CPSR中的T位;4.強制PC從地址0x00開始對下一條指令進行取指;5.返回到ARM狀態並恢復執行 。

R14(LR)寄存器與子程序調用

1.程序A執行過程中調用程序B;

2.程序跳轉至標號Lable,執行程序B。同時硬件將“BL  Lable”指令的下一條指令所在地址存入R14(LR);

3.程序B執行最後,將R14寄存器的內容放入PC,返回程序A;

ARM處理器共有7種工作模式:

①用戶模式 :非特權模式,也就是正常程序執行的模式,大部分任務在這種模式下執行。在用戶模式下,如果沒異常發生不允許應用程序自行改變處理器的工作模式,如果有異常發生,處理器會自動切換工作模式。

②FIQ模式 :也稱爲快速中斷模式,支持高速數據傳輸和通道處理,當一個高優先級(fast)中斷產生時將會進入這種模式。

③IRQ模式 :也成爲普通中斷模式,當一個低優先級(normal)中斷產生時將會進入這種模式。在這種模式下按中斷的處理器方式有分爲向量中斷和非向量中斷兩種。通常的中斷都在IRQ模式下進行。

④SVC模式 :稱之爲管理模式,它是一種操作系統保護模式。當復位或軟中斷指令執行時處理器進入這種模式。

⑤中止模式 :當存取異常時將會進入中止模式,用來處理存儲器故障、實現虛擬存儲或存儲保護。

⑥未定義指令異常模式:當執行未定義指令時會進入這種模式,主要是用來處理未定義的指令陷阱,支持硬件協處理的軟件仿真,因爲未定義指令多發生在協處理器的操作上。

⑦系統模式:使用和User模式相同寄存器組的特權模式,用來運行特權級的操作操作系統任務。

區別:特權模式--程序可以訪問所有的系統資源,也可以任意地進行處理器模式的切換。

ARM9採用5級流水線:取指、譯碼、執行、存儲器訪問、寄存器回寫。

·取指:從指令Cache中讀取指令。

·譯碼:對指令進行譯碼,識別出對哪個寄存器進行操作並從通用寄存器中讀取操作數。

·執行:進行ALU運算和移位操作,如果是對存儲器操作的指令,則在ALU中計算出要訪問的存儲器地址。

·存儲器訪問:如果是對存儲器訪問的指令,用來實現數據緩衝功能(通過數據Cache);如果不是對存儲器訪問的指令,本級流水線爲一個空的時鐘週期。

·寄存器回寫:將指令運算或操作結果寫回到目標寄存器中。

CISC:複雜指令集(Complex Instruction Set Computer)

具有大量的指令和尋址方式,指令長度可變;8/2原則:80%的程序只使用20%的指令;大多數程序只使用少量的指令就能夠運行。

RISC:精簡指令集(Reduced Instruction SetComputer)

只包含最有用的指令,指令長度固定;確保數據通道快速執行每一條指令;使CPU硬件結構設計變得更爲簡單

1.MOV指令與LDR指令都是往目標寄存器中傳送數據,但是它們有什麼區別嗎?

   MOV指令用於將數據從一個寄存器傳送到另一個寄存器中,或者將一個常數傳送到一個寄存器中,但是不能訪問內存。LDR指令用於從內存中讀取數據放入寄存器中。

 

1、ARM7TDMI-S各字母代表的含義?內核特點?採用幾級流水線,分別是?

ARM{x}{y}{z}{T}{D}{M}{I}{E}{J}{F}{-S}

大括號內的字母是可選的,各個字母的含義如下:

x         ——系列號,例如ARM7中的“7”、ARM9中的“9”;

y         ——內部存儲管理/保護單元,例如ARM72中的“2”、ARM94中的“4”;

z         ——內含有高速緩存Cache;

T        ——技持16位的Thumb指令集;

D        ——支持JTAG片上調試;

M       ——支持用於長乘法操作(64位結果)的ARM指令,包含快速乘法器;

I         ——帶有嵌入式追蹤宏單元ETM(Embedded Trace Macro),用來設置斷點和觀察點的調試硬件;

E        ——增強型DSP指令(基於TDMI);

J         ——含有Java加速器Jazelle,與Java虛擬機相比,Java加速器Jazelle使Java代碼運行速度提高了8倍,功耗降低到原來的80%;

F         ——向量浮點單元;

S——可綜合版本,意味着處理器內核是以源代碼形式提供的。這種源代碼形式又可以被編譯成一種易於EDA工具使用的形式。

內核特點:

32/16 位RISC架構(ARM v4T)。

具有最高性能和靈活性的32位ARM指令集。

代碼緊湊的16位Thumb指令集。

統一的總線接口,指令與數據都在32位總線上傳輸。

3級流水線。

32位算術邏輯單元(ALU)。

極小的核心尺寸以及低功耗。

協處理器接口。

擴展的調試設備:·EmbeddedICE-RT實時調試單元。 ·JTAG接口單元。 ·與嵌入式跟蹤宏單元(ETM)直接連接的接口。

ARM7系列內核採用了三級流水線的內核結構,三級流水線分別爲取指(Fetch)、譯碼(Decode)、執行(Execute)

·取指:將指令從存儲器中取出,放入指令Cache中。

·譯碼:由譯碼邏輯單元完成,是將在上一步指令Cache中的指令進行解釋,告訴CPU將如何操作。

·執行:這階段包括移位操作、讀通用寄存器內容、輸出結果、寫通用寄存器等。也就是將上一步中已被譯碼的指令進行邏輯電路實現。


1、排序

AREA TEXT,CODE,READWRITE  
    ENTRY  
    MOV R0,#100  ;循環數目  
    MOV R1,#0        ;初始化數據  
LOOP  
    ADD R1,R1,R0  ;將數據進行相加,獲得最後的數據  
    SUBS R0,R0,#1 ;循環數據R0減去1  
    CMP R0,#0        ;將R0與0比較看循環是否結束  
    BNE LOOP        ;判斷循環是否結束,接受則進行下面的步驟    
    LDR R2,=RESULT  
    STR R1,[R2]  
RESULT  
    DCD 0  
STOP  
    B STOP 
    ;排列算法:先將所有的數據與第一個進行比較,最後取出最小的數據放到第一個內存單元中  
    ;然後再從第二個內存單元開始進行比較,將第二小的數據放到第二個內存單元中,  
    ;以此內推則能將十個數據進行排列。  
    AREA TEXT,CODE,READWRITE  
    ENTRY  
    LDR R0,=DATA      ;獲得DATA數據的起始地址  
    MOV R1,R0      
    MOV R5,#9            ;開始的循環數目是10次,所以應該從9開始  
    MOV R6,R5  
COMPARE  
    ADD R0,R0,#4      ;將R0所存儲的地址+4表示爲下一個要比較的數的地址    
    SUB R6,R6,#1  ;循環1次減1  
    LDR R2,[R1]  ;將放在寄存器中的數據取出進行大小比較  
    LDR R3,[R0]  
    CMP R3,R2  
    MOVCC R7,R2  ;如果後面的地址的數值比前一個小則交換他們的數據  
    MOVCC R2,R3  
    MOVCC R3,R7  
    STR R2,[R1]  ;將數據存儲到相應的內存單元中  
    STR R3,[R0]  
    CMP R6,#0            ;看每次的循環是否結束  
    BNE COMPARE  
    ADD R1,R1,#4      ;每次循環結束以後將初始的指向的內存地址後移一個單元  
    MOV R0,R1            ;重新初始化上個循環中的寄存器中保存的地址  
    SUB R5,R5,#1      ;每次循環以後上面在以後的循環中的次數都會減1  
    MOV R6,R5  
    CMP R5,#0    ;判斷所有的循環是否結束  
    BNE COMPARE  
DATA  
    DCD 9,4,6,7,8,1,3,2,0,5  
STOP  
    B STOP 

C語言代碼:

#include<stdio.h>  
extern void strcopy(char *d, const char *s);  
int main()  
{  
    const char *srcstr="abcdefghi";  
    char dststr[]="ighfedcba";    
    strcopy(dststr,srcstr);  
    return 0;  
}   

ARM彙編代碼:

STACK_TOPEQU 0x40002000  
    PRESERVE8  
    AREA SCopy, CODE, READONLY  
    EXPORT START  
    EXPORT strcopy  
    import main  
    ENTRY  
START  
    LDR R13,=STACK_TOP  
    B main  
strcopy                  
    LDRB r2, [r1],#1  
    STRB r2, [r0],#1  
    CMP  r2, #0          
    BNE  strcopy          
    MOV  pc,lr        
    END 

stack_top equ0x40002000
PRESERVE8
export copy
AREA copy,CODE,READONLY
import copystr
export start
ENTRY
start
ldr r13,=stack_top
ldr r0,=src
ldr r1,=dst
BL copystr
src    
dcb "abcdefghij"
dst
dcb "helloworld"
end
//C程序
#include<stdio.h>
voidcopystr(char *d,char *s)
{
while((*d++=*s++)!='\0');
}

發佈了78 篇原創文章 · 獲贊 287 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章