ARM アーキテクチャ、コンパイルの概要

アーキテクチャ: さまざまな ARM プロセッサに共通の動作特性
プロセッサ: さまざまな設計に統合できるアーキテクチャを実装
デバイス: プロセッサと追加のコンポーネントが含まれる

ARM アーキテクチャには以下が含まれます。
    プログラミング モデル
    命令セット
    システム構成
    例外処理
    ストレージ モデル

プロセッサはさまざまなメモリ管理モデルを実装できます。
    MMU (メモリ管理ユニット) に基づく VMSA (仮想メモリ システム アーキテクチャ) MPU
    (メモリ保護ユニット) に基づく PMSA (保護メモリ システム アーキテクチャ)
    
ARMv7 はアーキテクチャ プロファイルを導入します:
    A はマイクロプロセッサを定義しますVMSA ベースのアーキテクチャ、高性能、オペレーティング システムの完全な機能をサポート
    R リアルタイムは、PMSA に基づいたマイクロプロセッサ アーキテクチャ、確定的な時間応答、低遅延割り込みを定義
    M マイクロコントローラーの低遅延割り込み処理 さまざまな例外処理ありモデルと PMSA
    
プロセッサ
    は特定のアーキテクチャ バージョンを実装します
    ARM926EJ-S は TEJ 拡張機能を備えた ARMv5 を実装します
    Cortex-A9 はマルチプロセッシング拡張機能を備えた ARMv7-A を実装します
    
デバイスは通常、ARM プロセッサと追加コンポーネントを統合した SOC です
    デバイスを実装するとき、キャッシュ サイズ、ハードウェアをサポートするかどうか浮動小数点ユニットなどはオプションの演算です。 

--------------------- ARMv5 アーキテクチャ ドキュメントの概要 ------------------- 7 つの
CPU モード
    : ユーザー、管理、システム、アボート、割り込み、高速割り込み、未定義
    7 つの例外: リセット SWI データのアボート プリフェッチのアボート 高速割り込み割り込み 未定義 リセット
    と SWI は管理モードに入る; メモリにアクセスできない、アボート モードに入る (命令フェッチ、データのフェッチ); フェッチされた命令はデコードできず、未定義 (命令) モードに入ります。
    ユーザー モードのみが非特権モードであり、一部のストレージ システムとコプロセッサには制限された権限があり、SWI 命令を通じて例外が生成され、別の特権プロセッサ モデルに切り替わります。 
    
    特権モードでは CPSR の完全な読み取りと書き込みが可能ですが、非特権モードでは制御ドメインの読み取りと条件フラグの読み取りと書き込みのみが可能です。    
    例外が発生した場合にのみ、CPSR が保存されます (自動的に?)。命令を使用して CPSR を書き換えますが、SPSR には保存されません;
    
CPSR [NZCV....IFT モード]
    IF 割り込みおよび高速割り込みマスク ビット
    N からの負の値上位 31 ビット
    Z ゼロの結果は 0
    C キャリーキャリー、
    V オーバーフロー
レジスタ:
    31 個の汎用レジスタ、同時に表示されるのは 16 個のみ R0 ~ R15 r13
    (SP)、r14(LR)、r15(PC)

    r0....r15 CPSR (ユーザー、システム)
    r0...r7 r8_fiq..r14_fiq CPSR、SPSR_fiq (高速割り込み)
    r0...r12 r13_irq r14_irq CPSR、SPSR_irq (割り込み)
    r0...r12 r13_svc r14_svc CPSR、 SPSR_svc (管理)
    r0...r12 r13_undef r14_undef CPSR、SPSR_undef (未定義)
    r0...r12 r13_abt r14_abt CPSR、SPSR_abt (中止)
    
    CP15 コプロセッサは、ストレージ コンポーネントを制御します: キャッシュ、バッファ、MMU MPU
条件付き実行
    EQ Z 等しい
    NE z Not
    CS/HS C 桁上げ位置 1/符号なし数値が
    CC/LO c 桁上げクリア 0/符号なし数値が MIN 未満 負のマイナス PL n 負でないプラス
    VS
    V 
    オーバーフロー
    VC v オーバーフローなし
    HI zC 符号なしLS Z/cより大きい
    符号なし 以下

    GE NV/nv 符号付き以上
    LE Z/Nv/nV 符号付き以下
    GT NzV/nzv 符号付き大きい
    LT Nv/nV 符号付き小さい

パイプライン
    ARM モードが現在の命令を「実行」すると、PC レジスタは +8 の位置を指します。
    命令がジャンプされると、ARM コアはパイプラインをクリアします。ただし、分岐予測テクノロジを通じて、分岐アドレスをロードできます。影響を軽減するために前進し、 
    中断されると、現在実行されている命令は完了し、パイプライン内の他の命令は破棄されます。

一般的な ARM 命令には 2 つのソース レジスタ Rn および Rm と 1 つのデスティネーション レジスタがあり、Rm は ALU に入る前にシフト前処理を実行できます。
構文: ADD r3,r2,r1 r3 デスティネーション、r2、r1 ソース レジスタ。

命令分類: データ処理、分岐、LOAD-STORE、割り込み、プログラムステータスレジスタ


データ処理命令 (MOV、算術、論理、比較、乗算) では、
    データ処理命令の前に S サフィックスが使用され、CPSR のフラグ ビット (NZCV) が更新されます。CMP は S を追加する必要がなく、CPSR を自動的に更新します。
    MOV 命令とロジック命令は C、N、Z に影響を与えます。


    MOV 構文: <命令>{<cond>}{S} Rd, N
    MOV Rd,N ; Rd = N
    MVN Rd,N ; Rd = ~N
    
    構文内の N は、レジスタ、即値、またはバレルです。シフタ前処理レジスタ Rm (R0、LSL #2 バレル シフタなど) は、
    オペランドが ALU に入る前に、指定された桁数だけオペランドの左/右シフトを実行します。これは現在の命令サイクル内で発生します。

    MOV r7, r5, LSL #2 ; r7 = r5<<2
    
    LSL 論理左シフト x LSL y x<<y
    LSR 論理右シフト x LSR y (符号なし)x>>y
    ASR 算術右シフト x ASR y (符号あり)x >>y 算術右シフトのみ符号付き;
    ROR 回転右シフト x ROR y ((unsigned)x>>y) | (x<<(32-y))
    RRX 拡張回転右シフト 1 ビット x RRX y ( c < < 31) | ((unsigned)x>>1) CPSR の C フラグ。

算術命令
    <instructions>{<cond>}{S} Rd、Rn、N

    ADD 32 ビット加算 Rd = Rn + N
    ADC キャリー付き 32 ビット加算 Rd = Rn + N + キャリー

    SUB 32 ビット減算 Rd = Rn - N
    SBC キャリー付き 32 ビット減算 Rd = Rn - N - !C

    RSB 逆減算 Rd = N - Rn
    RSC キャリー付き逆減算 Rd = N - Rn - !C

論理命令
    <instruction>{<cond>}{S} Rd, Rn, N
    AND Rd = Rn & N 論理 AND
    ORR Rd = Rn | N 論理 OR
    EOR Rd = Rn ^ N 論理 XOR
    BIC Rd = Rn & ~N 論理少しはっきりした

比較命令 (CPSR 自動更新)
    <命令>{<cond>} Rn, N
    CMP Rn - N
    CMN 比較 Rn + N 負比較
    TEQ Rn ^ N 等価性テスト
    TST Rn & N ビットテスト

乗算命令
    MLA {<cond>}{S} Rd,Rm,Rs,Rn; Rd=(Rm*Rs)+Rn 積和演算
    MUL {<cond>}{S} Rd,Rm,Rn; Rd=Rm* Rn乗算

    <コマンド> {<cond>}{S} RdLo、RdHi、Rm、Rs
    RdLo 下位 32 ビット、RdHi 上位 32 ビット; S 符号付き U 符号なし、末尾 L ロング整数
    SMLAL [RdHi, RdLo] = [RdHi, RdLo] + Rm*Rs
    SMULL [RdHi,RdLo] = Rm*Rs

    UMLAL [RdHi,RdLo] = [RdHi,RdLo] + Rm*Rs
    UMULL nb[RdHi,RdLo] = Rm*Rs

分岐命令
    B{<cond>} label   
    BL{<cond>} label  
    BX{<cond>} Rm  
    BLX{<cond>} Rm | label 

    B pc=label
    BL 後の最初の命令のアドレスにジャンプ pc=label,lr=BL
    BX pc=Rm&0xFFFFFFFE, T=Rm&1 ジャンプして状態を切り替える
    BLX pc=label,T=1; 
        pc=Rm&0xFFFFFFFE,T=Rm&1 、lr=BLX の後の最初の命令のアドレス ラベルは、
    PC を基準とした符号付きオフセットであり、32MB の範囲に制限されます。T は CPSR のサム ビットに対応します。BX
    /BLX の Rm は絶対アドレスであり、最下位ビットです。 Thumb 状態に切り替えるかどうかを示します。

LOAD-STORE 命令
    
単一レジスタ転送
    <LDR|STR>{<cond>}{B} Rd, addressing1
    LDR{<cond>}SB|H|SH Rd, addressing2
    STR{<cond>}H Rd,addressing2

    LDR レジスタにワードをロード 
    STR レジスタからワードを保存
    LDRB レジスタにバイトをロード
    STRB レジスタからバイトを保存
    LDRH ハーフワードをロード
    STRH ハーフワードをストア
    LDRSB 符号付きバイトをロード
    STRSH 符号付きバイトをストア

    LDR r0, [r1]; r1 が指すデータは r0 にロードされます
    STR r0, [r1]; r0 は r1 が指す場所に格納されます、r1 はベース レジスタと呼ばれます]

    単一レジスタ LOAD-STORE 命令のアドレッシング モード
    LDR r0, [r1,#4]! ; r1=r1+4; r0=*(r1); 
    LDR r0, [r1,#4] ; r0=*(r1+ 4) ;
    LDR r0, [r1], #4; r0=*r1; r1=r1+4
    
    概要: ロードされるデータは常に [] で指定されたデータであり、! またはオフセットが外側にあるデータはベース レジスタに書き戻される必要があります。

    バリアント:
    LDR r0, [r1,r2] ;
    LDR r0, [r1,r2, LSR #0x04]! ロード mem32[r1+(r2 LSR #0x04)],r1 = r1 + (r2 LSR 0x4) LDR r0, [
    r1 ,-r2,LSR #0x4] Load mem32[r1-(r2 LSR #0x04)]
    LDR r0, [r1], r2, LSR #0x04 Load mem32[r1], r1=r1+(r2 LSR 0x4)
    
マルチレジスタ転送
    割り込みの遅延を増やします;
    {LDM|STM}{<cond><addressing mode>Rn{!}, <Registers>{r^}

    LDM {Rd}*N < mem32[base+4*N] オプションの Rn 更新、メモリを複数のレジスタにロード
    STM {Rd}*N > mem32[base+4*N] オプションの Rn 更新、複数のレジスタをメモリに保存

---- アドレッシング モード 説明 開始アドレス 終了アドレス Rn! ----
    IA は実行後に Rn を増加させます Rn+4*N-4 Rn+4*N
    IB は実行前に Rn+4 Rn+4*N を増加させます 4*N DA     は実行後
    に Rn-4*N+4 Rn Rn-4*N だけ減らされますDB は実行前に Rn-4*N Rn-4 Rn-4*N だけ減らされます

    I が増加、D が減少、
    実行後に増加: 最初に該当するアドレスからデータをロードし、次のステップでロードするアドレスを更新します

    LDMIA r0!、{r1-r3}
    STMIB r0!、{r1-r3}

スタック操作
    ATPCS はスタックを完全減少として定義し、LDMFD、STMFD は
    それぞれポップとプッシュ A(昇順)、D(降順)に対応します; F(フル)sp が指す位置が使用されています; E が指す位置(Empty)sp は使用されていません;
    FA ----> Full Ascending 完全増加スタック          
    FD ----> Full Descending 完全減少スタック 
    EA ----> Empty Ascending 空増加スタック
    ED ----> Empty Descending空の減少スタック

スワップ命令
    SWP{B}{<cond>} Rd,Rm,[Rn]; tmp=mem32[Rn]; mem32[Rn]=Rm;Rd=tmp; SWPB バイト交換は、実行中に他の命令やバスでは使用できません
    。
    実行 システムが「バスを保持」している間にアクセス割り込みが
    行われます。交換命令は、オペレーティング システムでセマフォと相互排他操作を実装するために使用されます。
    
ソフト割り込み命令は
    通常、ユーザー モードで実行され、システム コールに使用されます。SWI
    { <cond> } SWI_Number
        1. lr_svc = SWI 後の命令アドレス
        2. spsr_svc = cpsr
        3. pc=vectors+8
        4. cpsr = svc
        5. cpsr_I = 1 (IRQ 割り込みをマスク)
    概要: CPU モードと割り込みマスク ビットを設定し、 にジャンプします。対応する割り込み処理関数。

プログラム ステータス レジスタ命令
    MRS{<cond>} Rd, <cpsr|spsr> ; Rd = psr
    MSR{<cond>} <cpsr|spsr>_<fields>, Rm ; psr[field] = Rm
    MSR{<cond> } <cpsr|spsr>_<フィールド>, #immediate ; psr[フィールド] = 即時

    MRS r1、cpsr
    BIC r1、r1、#0x80
    MSR cpsr_c、r1

コプロセッシング命令は、
    命令セットを拡張するために使用されます。これは、追加のコンピューティング能力を提供することと、キャッシュやメモリ管理を含むストレージ サブシステムを制御することの両方に使用できます。
    データ処理、レジスタ転送、メモリ転送命令が含まれます。命令はコプロセッサに固有です。
    CDP {<条件>} cp,opcode1,Cd,Cn {,opcode2}
    <MRC|MCR>{<条件>} cp,opcode1,Rd,Cn,Cm{,opcode2}
    <LDC|STC>{<条件>} cp、Cd、アドレス指定

    CDP コプロセッサ データ処理、コプロセッサ内部でデータ処理操作を実行、
    MRC MCR コプロセッサ レジスタ転送、コプロセッサ レジスタへのデータの送受信、コプロセッサ レジスタからのデータの送信、
    LDC STC コプロセッサ メモリ転送、コプロセッサからのロード /メモリ データ ブロックの保存、

    cp は、p0 ~ p15 の範囲のコプロセッサ番号を表します。
    CP15 はシステム用に予約されており、メモリ管理、書き込みバッファ制御、キャッシュ制御、およびレジスタ識別に使用されます。

コプロセッサ 15 (CP15) は、
    CP15 システムにコプロセッサを制御するように指示します。
    構成情報を保存するための専用レジスタセットを備えた構成可能なプロセッサコア

    MRC p15,0,r1,c1,c0,0; ​​C1 を r1 に書き込む

定数ロード
    ARM 命令は 32 ビットで、即値 (4 ビット オフセットと 8 ビット整数) の格納に 12 ビットを使用します。ARM は、
    32 ビット定数をレジスタに送信するための 2 つの疑似命令を追加します。実際の命令はコンパイラまたはアセンブラに選択させます。

    LDR Rd, =定数; 定数ロード
    ADR Rd, ラベル; アドレスロード

ゼロ カウント命令は、
    最上位の符号ビットと最初の 1 の間のゼロの数をカウントします。
    LDR r1,=0x00FFFFFF
    CLZ r0,r1; r0=8

=======================================
例外と割り込みの処理

    例外は、命令の通常の実行を中止する必要がある状況です。割り込みは特殊なタイプの例外であり、
    各例外によりプロセッサは特定のモードに入ります。さらに、CPSR を変更すると、特定のモードに入ることができます。

    例外によってモードが変更されると、カーネルは自動的に次の操作を行います:
    1. CPSR を対応する例外モードの SPSR に保存します;
    2. PC を対応する例外モードの LR に保存します;
    3. CPSR を対応する例外モードに設定します;
    4. PC を対応する例外処理に設定します プログラムのエントリ アドレス。
    
    例外と対応するモード
    ------------------------
    高速割り込み FIQ
    割り込み IRQ
    SWI/リセット SVC
    プリフェッチ/データ アボート アボート
    未定義 命令 未定義

ベクタテーブル(例外発生時のジャンプアドレスで構成されたテーブル)
    PC に対する B 分岐ジャンプ
    LDR pc, [pc,#offset]
    LDR pc, [pc,#-0xFF0] 
    MOV pc, #immediate

ベクタテーブルとプロセッサモード

    例外モード オフセット
    ------------------------
    リセット SVC 0x0
    未定義命令 UND 0x4    
    SWI SVC 0x08
    プリフェッチ中止 ABT 0x0C
    データ中止 ABT 0x10
    未割り当て --- 0x14
    IRQ IRQ 0x18
    FIQ FIQ 0x1C

例外優先度
    例外優先度 I ビット F ビット
    --------------------------------
    リセット 1 1
    1データ中止 2 1 -
    FIQ 3 1 1
    IRQ 4 1 -
    プリフェッチ中止 5 1 -
    SWI 6 1 -
    未定義命令 6 1 -

例外が発生すると、LR は現在の PC 値に基づいて特定の値に設定されます。
    IRQ の場合、LR=最後に実行された命令のアドレス + 8; LR は例外ハンドラーの戻りアドレスを保存します。
    
    LR レジスタ アドレスの使用法に基づく便利なアドレス
    例外
    ----------------------------
    リセット      
    --データ アボート lr-8 の原因となるポイントdata 例外を中止した命令
    FIQ lr-4     
    IRQ lr-4     
    中止されたプリフェッチ命令 lr-4    
    SWI lr SWI 命令の次の命令を指す
    未定義命令 lr 未定義命令の次の命令を指す

    handler
        <ハンドラー コード>
        ...
        SUBS pc, r14, #4;pc=r14-4.  
    SUBS の最後に [S] があり、PC は宛先レジスタです。SPSR は自動的に CPSR に復元されます。

アセンブリの例では、write システム コールを使用して「hello」を出力し、exit を呼び出して終了します。

.section .data

hello:
.ascii "hello\n"



.section .text
.globl _start

_start:

        mov r0, #1   //fd 1 stdout
        ldr r1, =hello  //buf addr
        mov r2, #6  //size 6
        mov r7, #4  //syscall write
        svc #0

        mov r0, #0  // exit status 0
        mov r7, #1  // syscall 1(exit)
        svc #0
all:
        as -g main.s -o main.o
        #ld -dynamic-linker /lib/ld-linux-aarch64.so.1 -lc  main.o -o a.out
        ld main.o -o a.out
        rm main.o

おすすめ

転載: blog.csdn.net/konga/article/details/84503279