訂閱
糾錯
加入自媒體

從0學(xué)ARM——什么是位置無關(guān)碼?

二、怎么實現(xiàn)位置無關(guān)碼?

1. 什么是《編譯地址》?什么是《運行地址》?

「編譯地址:」

32位的處理器,它的每一條指令是4個字節(jié),以4個字節(jié)存儲順序,進(jìn)行順序執(zhí)行,CPU是順序執(zhí)行的,只要沒發(fā)生什么跳轉(zhuǎn),它會順序進(jìn)行執(zhí)行, 編譯器會對每一條指令分配一個編譯地址,這是編譯器分配的,在編譯過程中分配的地址,我們稱之為編譯地址。

「運行地址:」

是指程序指令真正運行的地址,是由用戶指定的,用戶將運行地址燒錄到哪里,哪里就是運行的地址。比如有一個指令的編譯地址是0x40008000,實際運行的地址是0x40008000,如果用戶將指令燒到0x60000000上,那么這條指令的運行地址就是0x60000000。

當(dāng)編譯地址和運行地址不同的時候會出現(xiàn)什么結(jié)果?結(jié)果是不能跳轉(zhuǎn),編譯后會產(chǎn)生跳轉(zhuǎn)地址,如果實際地址和編譯后產(chǎn)生的地址不相等,那么就不能跳轉(zhuǎn)。

「C語言編譯地址:」

都希望把編譯地址和實際運行地址放在一起的,但是匯編代碼因為不需要做C語言到匯編的轉(zhuǎn)換,可以直接的去寫地址,所以直接寫的就是他的運行地址,這就是為什么任何bootloader剛開始會有一段匯編代碼,因為起始代碼編譯地址和實際地址不相等,這段代碼和匯編無關(guān),跳轉(zhuǎn)用的運行地址。

2. 舉例

實現(xiàn)位置無關(guān)碼主要考慮以下兩個方面:

1. 位置無關(guān)的函數(shù)跳轉(zhuǎn)
2. 位置無關(guān)的常量訪問

下面我們通過兩個例子詳細(xì)講解。

代碼

編譯代碼使用的連接文件「map.lds」如下:

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS

. = 0x40008000;
. = ALIGN(4);
.text      :

 gcd.o(.text)
 *(.text)

. = ALIGN(4);
   .rodata :
{ *(.rodata) }
   . = ALIGN(4);
   .data :
{ *(.data) }
   . = ALIGN(4);
   .bss :
    { *(.bss) }

如文件map.lds所示:「0x40008000」就是鏈接地址,

其他源文件如下:「gcd.s」

.text
.global _start
_start:
 ldr  sp,=0x70000000         get stack top pointer
 bl func
 ldr pc,=func
 b  main
func:
mv pc,lr

「main.c」


* main.c

*  Created on: 2020-12-12
*      Author: 一口Linux

int aaaa=0;
int main(void)

aaaa = 0x11;
while(1);
   return 0;

「Makefile」

TARGET=gcd
TARGETC=main
all:
arm-none-linux-gnueabi-gcc -O1 -g -c -o $(TARGETC).o  $(TARGETC).c
arm-none-linux-gnueabi-gcc -O1 -g -c -o $(TARGET).o $(TARGET).s
arm-none-linux-gnueabi-gcc -O1 -g -S -o $(TARGETC).s  $(TARGETC).c
arm-none-linux-gnueabi-ld $(TARGETC).o $(TARGET).o -Tmap.lds  -o  $(TARGET).elf
arm-none-linux-gnueabi-objcopy -O binary -S $(TARGET).elf $(TARGET).bin
arm-none-linux-gnueabi-objdump -D $(TARGET).elf > $(TARGET).dis
clean:
rm -rf *.o *.elf *.dis *.bin
反匯編文件「gcd.dis」

如上圖所示:

_start對應(yīng)的鏈接地址是0x400080009行 bl func對應(yīng)的指令10行 ldr pc,=pc對應(yīng)的指令func的鏈接地址0x40008010全局變量aaaa對應(yīng)的內(nèi)存位于bss段0x4000802c19行 aaaa = 0x11 賦值語句對應(yīng)的機器碼

<上一頁  1  2  3  下一頁>  
聲明: 本文由入駐維科號的作者撰寫,觀點僅代表作者本人,不代表OFweek立場。如有侵權(quán)或其他問題,請聯(lián)系舉報。

發(fā)表評論

0條評論,0人參與

請輸入評論內(nèi)容...

請輸入評論/評論長度6~500個字

您提交的評論過于頻繁,請輸入驗證碼繼續(xù)

暫無評論

暫無評論

人工智能 獵頭職位 更多
掃碼關(guān)注公眾號
OFweek人工智能網(wǎng)
獲取更多精彩內(nèi)容
文章糾錯
x
*文字標(biāo)題:
*糾錯內(nèi)容:
聯(lián)系郵箱:
*驗 證 碼:

粵公網(wǎng)安備 44030502002758號