新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > ARM編程進階之一-ARM匯編偽指令

        ARM編程進階之一-ARM匯編偽指令

        作者: 時間:2016-11-27 來源:網絡 收藏

        b)、編譯器是如何得出InitStack所代表的地址是0x64?

        編譯器知道MOV R0, LR這條指令相對于整個程序的第1條指令的偏移量為0x64;同時又知道這個程序將來在內存中的運行地址為0x0,所以編譯器在編譯的時候(不是程序運行的時候)就可以確定InitStack所代表的地址為0x64+0x0=0x64。那么編譯器又是如何知道“程序將來在內存中的運行地址”的呢?其實,這個“程序將來在內存中的運行地址”,我通常稱它為“程序的期望運行地址”,簡稱“運行地址”,以后我也將這樣稱呼它。它其實是在編譯程序前由程序員告知編譯器的。

        c)、如果將來程序并沒有運行在它的運行地址處,很顯然這個程序就會出問題。如何解決?

        出問題的原因,顯然是由于ldr偽指令使用的絕對地址。所以,解決的辦法就是使用相對地址,進行相對尋址。這就要用到我們下面要介紹的另一條偽指令adr

        2、adr

        ADR偽指令的作用與LDR偽指令的作用相同,都是將標號所代表的地址賦予寄存器,不過2者的實現機制是完全不同的:ldr采用絕對地址,adr采用相對地址。

        ADR偽指令將基于PC相對偏移的地址值讀取到寄存器中。在匯編源程序時,ADR偽指令被編譯器替換成一條合適的指令。通常,編譯器用一條ADD指令或SUB指令來實現該ADR偽指令的功能。

        很顯然,由于將ADR R0, Delay替換為ADD r0, pc, #0x3c,而它是以當前指令的地址(pc的值)進行相對地址計算的。所以即使將來程序沒有實際運行在運行地址處,也不會有問題。

        當然,這里還有2個問題:

        a)、既然adr和ldr完成類似的功能,adr又能避免絕對地址的問題,還要ldr偽指令有何用?

        這主要是因為,adr偽指令要求標號與adr偽指令必須在同一個段中(段的概念參見“ARM匯編偽操作”一文),而ldr偽指令則沒有這樣的要求。

        b)、add r0, pc, #0x3c中的常數0x3c是放在機器指令12bit中的立即數,這個立即數有可能不能被12bit表示出來。此時編譯會產生錯誤。如果出現這樣的情況,又應該如何辦?

        使用下面要講的偽指令adrl

        3、adrl

        在匯編源程序時,ADRL偽指令被編譯器替換成兩條合適的指令。其本質是:將偏移量這個立即數(可能不能被12bit表示出來)拆分為2個可以被12bit表示的立即數,然后用2條add(或sub)指令來替換adrl偽指令。

        當然你會問,如果那個立即數非常特殊,無論如何也拆分不成2個可以被12bit表示的立即數(也就是說需要拆分為3個甚至更多的數),那又應該如何辦?關于這個問題,我在這里不予回答,不過你要記住一句話,如果機器智能到啥都能做的話,你作為程序員就失業了!哈哈!

        4、nop

        NOP是no operation的意思,就是CPU不做任何事的意思。這里千萬要明白,CPU一旦上電就將永不停歇地運行,絕不可能有一條指令能另CPU什么都不做。所以,該偽指令在匯編時將會被代替成“MOV R0,R0”指令。

        NOP主要用于短延時操作,關于這一點,這里我要多說幾句。與應用程序不同,匯編程序通常要用于控制硬件,例如,你需要使用匯編程序要求某個硬件執行某個操作(例如:初始化nandflash),并要在該操作完成后才能進行后面的操作,而硬件從接到命令到完成該操作需要一段時間(該時間很短,但對CPU而言卻較長,通常需要幾個指令周期)。此時,程序員就必須在發出命令的指令和后續操作之間做延時,通常的做法就是加入幾個NOP偽操作。

        附:ldr指令與ldr偽指令的4種形式(這4種形式,極其容易讓初學者困惑,所以在此集中列出)

        ldr r0, [r1]指令,將內存存放的內容加載到r0中
        ldr r0, label指令,將標號label所代表的內存地址處存放的內容加載到r0中
        ldr r0, =10000偽指令,將常數10000賦予r0(采用ldr指令+文字池的方式實現)
        ldr r0, =lable偽指令,將標號label所代表的內存地址賦予r0


        上一頁 1 2 下一頁

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 宁晋县| 北碚区| 桂东县| 宜州市| 庆阳市| 平利县| 堆龙德庆县| 长葛市| 渑池县| 泾阳县| 定襄县| 吐鲁番市| 新巴尔虎右旗| 大足县| 连平县| 什邡市| 连州市| 明光市| 无锡市| 体育| 班玛县| 涪陵区| 平舆县| 牙克石市| 北票市| 炉霍县| 通州市| 泸西县| 吴江市| 额敏县| 德化县| 遵义市| 无极县| 慈利县| 灵台县| 上虞市| 新乡县| 罗田县| 丹棱县| 吴川市| 文昌市|