新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 加載時域和運行時域

        加載時域和運行時域

        作者: 時間:2016-11-10 來源:網絡 收藏
        內容摘自 《S3C2410完全開發流程》

        在開始后續實驗之前,我們得了解一下arm-linux-ld連接命令的使用。在上述實驗中,我們一直使用類似如下的命令進行連接:
        arm-linux-ld -Ttext 0x00000000 crt0.o led_on_c.o -o led_on_c_tmp.o
        我們看看它是什么意思:-o選項設置輸出文件的名字為led_on_c_tmp.o;“--Ttext 0x00000000”設置代碼段的起始地址為0x00000000;這條指令的作用就是將crt0.o和led_on_c.o連接成led_on_c_mp.o可執行文件,此可執行文件的代碼段起始地址為0x00000000。

        本文引用地址:http://www.104case.com/article/201611/317236.htm

        我們感興趣的就是“—Ttext”選項!進入LINK目錄,link.s代碼如下:
        1 .text
        2 .global _start
        3 _start:
        4 b step1
        5 step1:
        6 ldr pc, =step2
        7 step2:
        8 b step2
        Makefile如下:
        1 link:link.s
        2 arm-linux-gcc -c -o link.o link.s
        3 arm-linux-ld -Ttext 0x00000000 link.o -o link_tmp.o
        4 # arm-linux-ld -Ttext 0x30000000 link.o -o link_tmp.o
        5 arm-linux-objcopy -O binary -S link_tmp.o link
        6 arm-linux-objdump -D -b binary -m arm link >ttt.s
        7 # arm-linux-objdump -D -b binary -m arm link >ttt2.s
        8 clean:
        9 rm -f link
        10 rm -f link.o
        11 rm -f link_tmp.o

        實驗步驟:
        1.進入目錄LINK,運行make生成arm-linux-ld選項為“-Ttext 0x00000000”的反匯編碼ttt.s
        2.make clean
        3.修改Makefile:將第4、7行的“#”去掉,在第3、6行前加上“#”
        4.運行make生成arm-linux-ld選項為“-Ttext 0x30000000”的反匯編碼ttt2.s
        link.s程序中用到兩種跳轉方法:b跳轉指令、直接向pc寄存器賦值。我們先把在不同“—Ttext”選項下,生成的可執行文件的反匯編碼列出來,再詳細分析這兩種不同指令帶來的差異。
        ttt.s: ttt2.s
        0: eaffffff b 0x4 0: eaffffff b 0x4

        4: e59ff000 ldr pc, [pc, #0] ; 0xc 4: e59ff000 ldr pc, [pc, #0] ; 0xc
        8: eafffffe b 0x8 8: eafffffe b 0x8
        c: 00000008 andeq r0, r0, r8 c: 30000008 tsteq r0, #8 ; 0x8
        先看看b跳轉指令:它是個相對跳轉指令,其機器碼格式如下:

        Cond101Loffset

        [31:28]位是條件碼;[27:24]位為“1010”時,表示B跳轉指令,為“1011”時,表示BL跳轉指令;[23:0]表示偏移地址。使用B或BL跳轉時,下一條指令的地址是這樣計算的:將指令中24位帶符號的補碼立即數擴展為32(擴展其符號位);將此32位數左移兩位;將得到的值加到pc寄存器中,即得到跳轉的目標地址。我們看看第一條指令“b step1”的機器碼eaffffff:
        1. 24位帶符號的補碼為0xffffff,將它擴展為32得到:0xffffffff
        2.將此32位數左移兩位得到:0xfffffffc,其值就是-4
        3.pc的值是當前指令的下兩條指令的地址,加上步驟2得到的-4,這恰好是第二條指令step1的地址
        各位不要被被反匯編代碼中的“b 0x4”給迷惑了,它可不是說跳到絕對地址0x4處執行,絕對地址得像上述3個步驟那樣計算。您可以看到b跳轉指令是依賴于當前pc寄存器的值的,這個特性使得使用b指令的程序不依賴于代碼存儲的位置——即不管我們連接命令中“--Ttext”為何,都可正確運行。
        再看看第二條指令ldr pc, =step2:從反匯編碼“ldr pc, [pc, #0]”可以看出,這條指令從內存中某個位置讀出數據,并賦給pc寄存器。這個位置的地址是當前pc寄存器的值加上偏移值0,其中存放的值依賴于連接命令中的“--Ttext”選項。執行這條指令后,對于ttt.s,pc=0x00000008;對于ttt2.s, pc=0x30000008。于是執行第三條指令“b step2”時,它的絕對地址就不同了:對于ttt.s,絕對地址為0x00000008;對于ttt.s,絕對地址為0x30000008。
        ttt2.s上電后存放的位置也是0,但是它連接的地址是0x30000000。我們以后會經常用到“存儲地址和連接地址不同”(術語上稱為加載時域運行時域)的特性:大多機器上電時是從地址0開始運行的,但是從地址0運行程序在性能方面總有很多限制,所以一般在開始的時候,使用與位置無關的指令將程序本身復制到它的連接地址處,然后使用向pc寄存器賦值的方法跳到連接地址開始的內存上去執行剩下的代碼。在實驗5、6中,我們將會作進一步介紹。
        arm-linux-ld命令中選項“-Ttext”也可以使用選項“-Tfilexxx”來代替,在文件filexxx中,我們可以寫出更復雜的參數來使用arm-linux-ld命令——在實驗6中,我們就是使用這種方法來指定連接參數的。



        關鍵詞: 加載時域運行時

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 莱芜市| 繁峙县| 赫章县| 斗六市| 长宁县| 南和县| 景东| 丹棱县| 虎林市| 望江县| 沿河| 金门县| 饶平县| 成都市| 南京市| 剑河县| 神农架林区| 广水市| 永州市| 乐至县| 怀化市| 洪洞县| 枣强县| 贵定县| 金寨县| 唐山市| 新乐市| 湘潭市| 新余市| 景宁| 内江市| 东台市| 古丈县| 尼玛县| 东乌珠穆沁旗| 宝清县| 丹江口市| 曲靖市| 丹棱县| 天峻县| 乐亭县|