2009年11月12日 星期四

ARM的組合語言與指令集,part 2.載入與存回

用來對記憶体存取指令,且分為二大類功能

  • 從單一暫存器存回(store)到記憶体中或從記憶体中載入(load)到暫存器
  1. 載入存回32bit的字組(word) ,與 無 正負的位元組(unsigle byte)
  2. 載入存回16bit的字組(half-word) ,與  正負的位元組(signed byte)
  • 將多個暫存器存回/載入 記憶体(LDM,load multiple)(STM,store multiple)或............
因其記憶体中,有多種定址方法
  1. 偏移量
  • 立即值:給定一個 無 正負號的值. (針對word,unsignel,立即值長度為12;另一為8bit
  • 指定暫存器: 給定一個一般暫存器
  • 比例化暫存器法(scaled register):指定一個暫存器,加上對此暫存器的移位運算得到偏移值.且只可以用在word,unsignel byte資料的存取指令
    2.前索引(pre-index):                                                                                                                     
              記憶体位址是由基底暫存器的值與偏移量直接加減得出,但基底暫存器的值可以根據新      產生的位址自動更新



        3.後索引(post-indexed):
           基底暫存器的值會先用來當所要存取記憶体位址,後...基底暫存器的值會與偏移量直接做加減運算,運算後的值存回到基底暫存器.

    -----------------------------------------------
    單一word和unsigned byte

    LDR | STR  {<條件式>} {B} Rd,[Rn,<偏移量>]  LDR r1,[r2,#8]    ; r1=*(R2+8)
      LDRB r1,[R2]     ;r1[7:0]=*r2 & r1[31:8]=0
      STR r2,[r1,#-8]  ;*(r1-8)=r2
      LDR r0,[r1,r2,lsl #1] ;r0=*(r1+(r2<<1))

    LDR | STR {<條件式>}{B} Rd,[rn],偏移量
      LDR R0,[R1],#8  ; r0=*r1 then r1=r1+8
      LDR r0,[r1],r2      ; r0=*r1 then r1=r1+r2

     LDR | STR {<條件式>}{B} Rd,程式標籤
      LDR R0,test
    test dcd 1000

    單一Halfword 和 signed byte

     LDR | STR {<條件式>} H|SH|SB Rd,[Rn,<偏移量>] {!}
       ldrh  r1,[r0]  ; r1[15:0]=*r0,r1[31:16]=0
       ldrh  r1,[r2,#2] ; r1[15:0]=*(r2+2)
       lstrh r1,[r2,#-2] ! ; *(r2-2)=r1[15:0] then r2=r2-2

     LDR | STR {<條件式>} H|SH|SB Rd,[Rn],<偏移量>
       ldrh r1,[r2] ,#2   ;r1[15:0]=*r2, r2=r2 +2


    LDM.在於一個指令可以從記憶体載入多筆資料到一般用途暫存器;
    STM:可以將多個暫存器的資料由一個指令寫回記憶体

    LDM {<條件式>} <定址模式> Rd {!} ,<暫存器組> {^}
      LDMIA R0 ! ,{R1-R4,PC}
       ; R1=*R0
       ; R2=*R0+4
       ; R3=*R0 +8
       ; R4=*R0+12
       ;PC=*R0+16,then R0=r0+20
    STM {<條件式>} <定址模式> Rd {!} ,<暫存器組> {^}
      STMIA R0,{R1-R4,LR}
      ;*R0=R1
      ;*R0+4=R2
      ;*R0+8=R3
      ;*R0+12=R4
      ;*R0+16=LR ,then R0=R0

    ps:
    定址法

    Full Ascending(FA)::
          指令為LDMFA/STRFA,代表堆疊往高位址的記憶体空間升長,而基底暫存器指到堆疊最頂的有效資料位址
    Full Descending(FD)::
         指令為LDMFD/STRFD,代表堆疊往低位址的記憶体空間升長,而基底暫存器指到堆疊最底的有效資料位址
    Empty Ascending(EA)::
          指令為LDMEA/STREA,代表堆疊往高位址的記憶体空間升長,而基底暫存器指到堆疊最頂的有效資料位址 再往上的空資料

    Empty Descending(ED)::
          指令為LDMED/STRED,代表堆疊往低位址的記憶体空間升長,而基底暫存器指到堆疊最底端的有效資料位址 再往下的空資料


    full ascendingLDMFA=LDMDASTMFA=LDMIB
    full descendingLDMFD=LDMIASTMFD=STMDB
    empty ascendingLDMEA=LDMDBSTMEA=STMIA
    empty descendingLDMED=LDMIBSTMED=STMDA
    也可以看成為 , 對堆疊動作 分為 (記這個比較清楚
    執行前累加(IB,increment before),其基底指到堆疊
    執行前遞減(DB,decrement before),其基底指到堆疊
    執行後累加(IA,increment after),其基底指到堆疊
    執行後遞減(DA,decrement after,其基底指到堆疊

    ps:
    在使用多原始檔時,需要指定其第一個開始區塊
    ROM_LOAD 0x00000000 0x00001000
        {
        ROM_EXEC 0x00000000    0x00000100
            {
                4_7_1.o (subclass,+First)   
                   
                *(+RO)                   
            }
        }

    沒有留言:

    張貼留言