新聞中心

    EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > ARM匯編語言(4) 指令、偽操作、偽指令學(xué)習(xí)

    ARM匯編語言(4) 指令、偽操作、偽指令學(xué)習(xí)

    作者: 時間:2016-11-10 來源:網(wǎng)絡(luò) 收藏
    LDR指令與LDR偽指令的4種形式:

    LDR R0,[R1]:指令,將R1指向的內(nèi)存地址存放的內(nèi)容加載到R0中;

    本文引用地址:http://butianyuan.cn/article/201611/317563.htm

    LDR R0,LABEL:指令,將標號LABEL所代表的內(nèi)存地址處存放的內(nèi)容加載到R0中;

    LDR R0,=10000:偽指令,將常熟10000賦予R0,采用LDR指令+文字池的方式實現(xiàn);

    LDR R0,=LABEL:偽指令,將標號LABEL所代表的內(nèi)存地址賦予R0;

    指令部分:

    偽操作部分:

    符號定義偽操作:定義變量,對變量進行賦值,定義寄存器名稱

    GBLA:全局的算術(shù)變量,初始化為0;

    GBLL:全局的邏輯變量,初始化為{FALSE};

    GBLS:全局的串變量,初始化為“”;

    LCLA:局部的算術(shù)變量,初始化為0;

    LCLL:局部的邏輯變量,初始化為{FALSE};

    LCLS:局部的串變量,初始化為“”;

    SETA:給算術(shù)變量賦值;

    SETL:給邏輯變量賦值;

    SETS:給串變量賦值;

    RLIST:為一個通用寄存器列表定義名稱;

    CN:為一個協(xié)處理器的寄存器定義名稱;

    CP:為一個協(xié)處理器定義名稱;

    DN:為一個雙精度的VFP寄存器定義名稱;

    SN:為一個單精度的VFP寄存器定義名稱;

    FN:為一個FPA浮點寄存器定義名稱;

    數(shù)據(jù)定義偽操作

    LTORG:聲明一個數(shù)據(jù)緩沖池的開始;

    MAP:定義一個結(jié)構(gòu)化的內(nèi)存表的首地址,同義詞為^;

    FIELD:定義一個結(jié)構(gòu)化內(nèi)存表中的數(shù)據(jù)域,同義詞#;

    SPACE:分配一塊內(nèi)存單元,并用0初始化,同義詞%;

    {label} SPACE exprexpr表示分配的內(nèi)存字節(jié)數(shù);

    DCB:分配一段字節(jié)內(nèi)存單元,并用expr初始化之,同義詞=;

    {label} DCB expr, {expr}...expr是-128~255的數(shù)值或字符串;

    DCD,DCDU:分配一段字內(nèi)存單元,分配的內(nèi)存都是字對齊的,并用expr初始化之,同義詞&,DCDU分配的內(nèi)存單元不嚴格字對齊;

    DCDO:分配一段字內(nèi)存單元,分配的內(nèi)存都是字對齊的,并將每個字單元的內(nèi)容初始化為expr標號基于靜態(tài)基址寄存器R9的偏移量;

    DCFD,DCFDU:

    DCFS,DCFSU:

    DCI:(ARM)分配一段字內(nèi)存單元,分配的內(nèi)存都是字對齊的,并用expr初始化;(Thumb)分配一段半字內(nèi)存單元,分配的內(nèi)存都是半字對齊的,并用expr初始化;

    DCQ,DCQU:

    DCW,DCWU:

    匯編控制偽操作

    IF,ELSE,ENDIF:根據(jù)條件將一段源代碼包括在匯編語言程序中或者將其排除在程序之外;

    IF logical expression

    instructions or directives

    ELSE

    instructions or directives

    ENDIF

    WHILE,WEND:根據(jù)條件重復(fù)匯編相同的或者幾乎相同的一段源代碼;

    WHILE logical expression

    instructions or directives

    WEND

    MACRO,MEND:定義宏定義體;

    MEXIT:從宏中跳轉(zhuǎn)出去;

    棧中數(shù)據(jù)幀描述偽操作;

    信息報告?zhèn)尾僮鳎?/p>

    其它偽操作:

    CODE16,CODE32:

    EQU:為數(shù)字常量,基于寄存器的值和程序中的標號定義一個字符名稱,同義詞*;

    name EQU expr {, type}

    AREA:

    ENTRY:

    END:

    ALIGN:

    EXPORT:

    GLOBAL:

    IMPORT:

    EXTERN:

    GET:

    INCLUDE:

    INCBIN:

    KEEP:

    NOFP:

    REQUIRE:

    REQUIRE8:

    PRESERVE8:

    RN:

    ROUT:

    偽指令部分:偽指令不是真正的指令,在匯編編譯器對源程序進行匯編處理時被替換成對應(yīng)的ARM或者Thumb指令;

    ADR(小范圍的地址讀取偽指令):將基于PC的地址值或者基于寄存器的地址值讀取到寄存器中;

    ADR{cond} register, expr

    expr是基于PC或者基于寄存器的地址表達式,取值范圍如下:

    地址值不是字對齊時,取值范圍-255~255;

    地址值是字對齊時,取值范圍-1020~1020;

    地址值是16字節(jié)對齊時,取值范圍更大;

    ADRL(中等范圍的地址讀取偽指令):將基于PC的地址值或者基于寄存器的地址值讀取到寄存器中;

    ADRL{cond} register, expr

    expr是基于PC或者基于寄存器的地址表達式,取值范圍如下:

    地址不是字對齊時,-64KB~64KB;

    地址是字對齊時,-256KB~256KB;

    地址是16字節(jié)對齊時,取值范圍更大;

    LDR:將一個32位的常數(shù)或者一個地址值讀取到寄存器中;

    LDR{cond} register, ={expr | label-expr}

    expr為32位常量;

    label-expr為基于PC的地址表達式或者外部表達式;

    NOP:匯編時被替換成ARM中的空操作;

    實例程序:

    1、

    AREA LDR_Code, CODE, READONLY
    ENTRY

    LDR r0, =src
    LDR r1, =dst
    MOV r2, r0
    MOV r3, r1
    MOV r5, #100
    LDR r6, =100
    LDR r7, =999999




    srcDCD 0, 1;, 2, 3, 4, 5, 6, 7, 8, 9
    dstDCD 0, 0;, 0, 0, 0, 0, 0, 0, 0, 0


    END

    反匯編代碼:

    $a
    LDR_Code
    0x00000000: e59f0024 $... LDR r0,0x2c
    0x00000004: e59f1024 $... LDR r1,0x30
    0x00000008: e1a02000 . .. MOV r2,r0
    0x0000000c: e1a03001 .0.. MOV r3,r1
    0x00000010: e3a05064 dP.. MOV r5,#0x64
    0x00000014: e3a06064 d`.. MOV r6,#0x64
    0x00000018: e59f7014 .p.. LDR r7,0x34
    src
    $d
    0x0000001c: 00000000 .... DCD 0
    0x00000020: 00000001 .... DCD 1
    dst
    0x00000024: 00000000 .... DCD 0
    0x00000028: 00000000 .... DCD 0
    0x0000002c: 0000001c .... DCD 28
    0x00000030: 00000024 $... DCD 36
    0x00000034: 000f423f ?B.. DCD 999999

    (1)為LDR偽指令生成的代碼,似乎有問題,不是基于PC的值,還是有默認的規(guī)則?

    使用GNU ARM Assembly將上面的代碼重新實現(xiàn)一次:

    .section .text
    .global _start
    _start:
    LDR r0, =src
    LDR r1, =dst
    LDR r2, =1000
    LDR r3, =5555


    MOV r4, r2
    MOV r5, r3


    .section .data
    src: .word 0, 0
    dst: .word 0, 1

    編譯通過了,不確定代碼有沒有問題,后面再檢查

    將上面的代碼使用arm-none-eabi-as編譯不鏈接,然后使用arm-none-eabi-objdump反匯編:

    Disassembly of section .text:


    00000000 <_start>:
    0: e59f0010 ldr r0, [pc, #16] ; 18 <_start+0x18>
    4: e59f1010 ldr r1, [pc, #16] ; 1c <_start+0x1c>
    8: e3a02ffa mov r2, #1000 ; 0x3e8
    c: e59f300c ldr r3, [pc, #12] ; 20 <_start+0x20>
    10: e1a04002 mov r4, r2
    14: e1a05003 mov r5, r3
    18: 00000000 andeq r0, r0, r0
    1c: 00000008 andeq r0, r0, r8
    20: 000015b3 strheq r1, [r0], -r3

    誠如文檔中對LDR的介紹:

    LDR r0, =src
    LDR r1, =dst
    LDR r2, =1000
    LDR r3, =5555

    這四條命令都進行了處理,以LDR r0, =src為例:

    0: e59f0010 ldr r0, [pc, #16] ; 18 <_start+0x18>

    src的值被存儲,ldr指令將[pc, #16]地址中的值加載到寄存器r0中,

    ARM處理器中,pc的值為當(dāng)前執(zhí)行的指令的地址值加上8,因此,執(zhí)行該條

    指令時,pc的值為8,此時pc加上16,則為十進制的24,十六進制的

    0x18,但是此時地址單元0x18中存儲的卻是一條指令:

    andeq r0, r0, r0

    為什么?

    將之前編譯生成的.o文件使用arm-none-eabi-ld進行連接,生成可執(zhí)行文件,

    然后反匯編,此時代碼變?yōu)椋?/p>

    Disassembly of section .text:


    00008000 <_start>:
    8000: e59f0010 ldr r0, [pc, #16] ; 8018 <_start+0x18>
    8004: e59f1010 ldr r1, [pc, #16] ; 801c <_start+0x1c>
    8008: e3a02ffa mov r2, #1000 ; 0x3e8
    800c: e59f300c ldr r3, [pc, #12] ; 8020 <_start+0x20>
    8010: e1a04002 mov r4, r2
    8014: e1a05003 mov r5, r3


    8018: 00010024 andeq r0, r1, r4, lsr #32
    801c: 0001002c andeq r0, r1, ip, lsr #32
    8020: 000015b3 strheq r1, [r0], -r3

    此時,src的值應(yīng)該存放在0x8000 + 8 + 16,8和16都是十進制的,因此應(yīng)該是0x8018,

    但是0x8018地址單元中為:

    andeq r0, r1, r4, lsr #32

    lsr在上一篇尋址方式中有所介紹,此時r4中的值通過上面的指令可知為十進制的1000,十六進制的0x3E8,

    0x3E8的二進制:

    0000 0000 0000 0000 0000 0011 1110 1000,執(zhí)行l(wèi)sr #32操作,右移32位,則變?yōu)?,

    r1中此時不管是什么值,AND指令執(zhí)行按位取與操作,指令的執(zhí)行結(jié)果自然是0,存放到r0寄存器中?

    此處應(yīng)該是個pool?為什么是指令?

    (2)$a、$d分別表示什么意思?

    摘錄自:Using asThegnuAssembler的Mapping Symbols章節(jié)

    The ARM ELF specification requires that special symbols be inserted into object files to
    mark certain features:
    $a At the start of a region of code containing ARM instructions.
    $t At the start of a region of code containing THUMB instructions.
    $d At the start of a region of data.

    待補充...



    關(guān)鍵詞: ARM匯編語言偽操作偽指

    評論


    技術(shù)專區(qū)

    關(guān)閉