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

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > Arm匯編 位置無關(guān)代碼 adr 指令

          Arm匯編 位置無關(guān)代碼 adr 指令

          作者: 時(shí)間:2016-11-09 來源:網(wǎng)絡(luò) 收藏
          adr r0, _start 得到的是_start的當(dāng)前執(zhí)行位置,由 pc+offset 決定的 得到有效地址
          ldr r0, =_start 得到的是絕對的地址,鏈接時(shí)決定;
          ------------------------------------------------------------------------
          /* 重定位Boot代碼到RAM內(nèi)存,將Boot代碼從FLASH移到RAM中 */
          relocate: /* relocate U-Boot to RAM */
          adr r0, _start /* r0 <- current position of code */
          /**************************************************************************
          * 把_start的相對地址移到r0, 相對尋址以程序計(jì)數(shù)器PC 的當(dāng)前值為基地址,
          * 指令中的地址標(biāo)號(hào)作為偏移量,將兩者相加之后得到操作數(shù)的有效地址。
          * 它是與位置無關(guān)的,主要看Boot在哪里運(yùn)行,也就是PC指針在哪里 (假設(shè)_start偏移量為0),
          * 例如這段代碼在 0x02000000 (FLASH起始地址)運(yùn)行,即此時(shí)PC=0x02000000,那么 adr r0, _start 得到 r0 = 0x02000000;
          * 如果在地址 0x81008000(Boot在RAM中加載地址)運(yùn)行,即此時(shí)PC=0x81008000,那么r0就是 0x81008000 了。
          *
          * 此處要注意ldr與adr的區(qū)別,看下面的代碼片段:
          * ldr r0, _start
          * adr r0, _start
          * ldr r0, =_start
          * nop
          * mov pc, lr
          * _start:
          * nop
          * 下面是反匯編的結(jié)果:
          * 0c008000 <_start-0x14>:
          * c008000: e59f000c ldr r0, [pc, #12] ; c008014 <_start>
          * c008004: e28f0008 add r0, pc, #8 ; 0x8
          * c008008: e59f0008 ldr r0, [pc, #8] ; c008018 <_start+0x4>
          * c00800c: e1a00000 nop (mov r0,r0)
          * c008010: e1a0f00e mov pc, lr
          *
          * 0c008014 <_start>:
          * c008014: e1a00000 nop (mov r0,r0)
          *
          * 分析:
          * ldr r0, _start
          * 從內(nèi)存地址 _start 的地方把值讀入。執(zhí)行這個(gè)后,r0 = 0xe1a00000
          *
          * adr r0, _start
          * 取得 _start 的地址到 r0,但是請看反編譯的結(jié)果,它是與位置無關(guān)的。其實(shí)取得的是相對的位置。例如這段代碼在 0x0c008000 運(yùn)行,
          * 那么 adr r0, _start 得到 r0 = 0x0c008014;如果在地址 0 運(yùn)行,就是 0x00000014 了。即當(dāng)前PC值加上_start的偏移量。
          *
          * ldr r0, =_start
          * 這個(gè)取得標(biāo)號(hào) _start 的絕對地址。這個(gè)絕對地址是在 link 的時(shí)候確定的??瓷先ミ@只是一個(gè)指令,但是它要占用 2 個(gè) 32bit 的空間,
          * 一條是指令,另一條是 _start 的數(shù)據(jù)(因?yàn)樵诰幾g的時(shí)候不能確定 _start 的值,所以不能直接用 mov 指令來給 r0 賦一個(gè) 32bit 的常量,
          * 所以需要多出一個(gè)空間存放 _start 的真正數(shù)據(jù),這個(gè)數(shù)據(jù)是在 link 的時(shí)候確定的,在這里就是 0x0c008014)。
          * 因此可以看出,這個(gè)是絕對的尋址,不管這段代碼在什么地方運(yùn)行,它的結(jié)果都是 r0 = 0x0c008014
          **************************************************************************/


          評論


          技術(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); })();