<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

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

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

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

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

          本文引用地址:http://www.ex-cimer.com/article/201611/317563.htm

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

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

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

          指令部分:

          偽操作部分:

          符號(hào)定義偽操作:定義變量,對(duì)變量進(jìn)行賦值,定義寄存器名稱

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

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

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

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

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

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

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

          SETL:給邏輯變量賦值;

          SETS:給串變量賦值;

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

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

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

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

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

          FN:為一個(gè)FPA浮點(diǎn)寄存器定義名稱;

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

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

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

          FIELD:定義一個(gè)結(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)存都是字對(duì)齊的,并用expr初始化之,同義詞&,DCDU分配的內(nèi)存單元不嚴(yán)格字對(duì)齊;

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

          DCFD,DCFDU:

          DCFS,DCFSU:

          DCI:(ARM)分配一段字內(nèi)存單元,分配的內(nèi)存都是字對(duì)齊的,并用expr初始化;(Thumb)分配一段半字內(nèi)存單元,分配的內(nèi)存都是半字對(duì)齊的,并用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ù)幀描述偽操作;

          信息報(bào)告?zhèn)尾僮鳎?/p>

          其它偽操作:

          CODE16,CODE32:

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

          name EQU expr {, type}

          AREA:

          ENTRY:

          END:

          ALIGN:

          EXPORT:

          GLOBAL:

          IMPORT:

          EXTERN:

          GET:

          INCLUDE:

          INCBIN:

          KEEP:

          NOFP:

          REQUIRE:

          REQUIRE8:

          PRESERVE8:

          RN:

          ROUT:

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

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

          ADR{cond} register, expr

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

          地址值不是字對(duì)齊時(shí),取值范圍-255~255;

          地址值是字對(duì)齊時(shí),取值范圍-1020~1020;

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

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

          ADRL{cond} register, expr

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

          地址不是字對(duì)齊時(shí),-64KB~64KB;

          地址是字對(duì)齊時(shí),-256KB~256KB;

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

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

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

          expr為32位常量;

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

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

          實(shí)例程序:

          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的值,還是有默認(rèn)的規(guī)則?

          使用GNU ARM Assembly將上面的代碼重新實(shí)現(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

          誠如文檔中對(duì)LDR的介紹:

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

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

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

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

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

          指令時(shí),pc的值為8,此時(shí)pc加上16,則為十進(jìn)制的24,十六進(jìn)制的

          0x18,但是此時(shí)地址單元0x18中存儲(chǔ)的卻是一條指令:

          andeq r0, r0, r0

          為什么?

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

          然后反匯編,此時(shí)代碼變?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

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

          但是0x8018地址單元中為:

          andeq r0, r1, r4, lsr #32

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

          0x3E8的二進(jìn)制:

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

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

          此處應(yīng)該是個(gè)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.

          待補(bǔ)充...



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

          評(píng)論


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

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();