KG—MOV指令,、LDR指令、LDR偽指令之間的區(qū)別 作為一個(gè)擴(kuò)展(KG),,感覺這個(gè)東西還是有必要說說的~~ 在我編譯一個(gè)工程的時(shí)候,,用MOV指令編譯有的時(shí)候出錯(cuò),但是有的時(shí)候就又對(duì)了,,還有LDR,,怎么有的時(shí)候加個(gè)“=”有的時(shí)候有不加了,,暈頭暈鬧的~~ 查過相關(guān)資料后,發(fā)現(xiàn)還是有很多要知道的~~ 1,、“8位圖”數(shù)據(jù) 這個(gè)是必須的必要知道的~~ 看一張圖片就明白了(右移~~): MOV指令可以把立即數(shù)或者寄存器內(nèi)容(注意:這里絕對(duì)不可以是內(nèi)存!?。﹤鬟f給一個(gè)寄存器。 對(duì)于立即數(shù)是有要求的,,就是上邊的“8位圖”數(shù)據(jù),。只能由一個(gè)8bit連續(xù)有效位通過偶數(shù)次移位得到的數(shù)。 它為什么會(huì)有這樣的限制呢,? 原因是,,MOV本身就是一個(gè)32bit指令,,除了指令碼本身,他不可能再帶一個(gè)可以表示32bit的數(shù)字,,所以用了 其中的12bit來表示立即數(shù),,其中4bit表示移位的尾數(shù)(循環(huán)右移,且數(shù)值*2),,8bit 用來表示要移位的一個(gè)基數(shù),。 如果立即數(shù)超過這個(gè)范圍,就沒有辦法用一條MOV指令給寄存器賦值(這里就要用到LDR偽指令了,,查看反匯編指令,,你會(huì)看到LDR偽指令此變成了兩條指令~~),。 3,、LDR指令 首先呢: ldr指令既可以是大范圍的地址讀取偽指令,也可以內(nèi)存訪問指令,。當(dāng)它的第二個(gè)參數(shù)前面有“=”時(shí),, 表示偽指令,否則表示內(nèi)存訪問指令,。 LDR指令就是個(gè)單寄存器存儲(chǔ)的ARM存儲(chǔ)器訪問指令,。 補(bǔ)充了MOV指令不能訪問內(nèi)存的缺陷。 ARM是RISC結(jié)構(gòu)的,,數(shù)據(jù)從內(nèi)存到CPU之間的移動(dòng)只能通過ldr/str指令(我說的是但個(gè)寄存器~~)。 想要把數(shù)據(jù)從內(nèi)存中某處讀取到寄存器中,,只能用ldr,。 在X86這種CISC構(gòu)架的就沒有l(wèi)dr,因?yàn)閄86一個(gè)mov就搞定了,,可以說這就是連個(gè)芯片之間最大的區(qū)別了~~ 4、LDR偽指令 1) LDR偽指令沒有立即數(shù)范圍的限制,,既,,可以直接賦值。因?yàn)檫@是一條偽指令,。 如果立即數(shù)在MOV的要求內(nèi),,系統(tǒng)會(huì)自動(dòng)用一條匯編MOV指令來實(shí)現(xiàn),。如果不在MOV的范圍內(nèi),就用其它的方式來實(shí)現(xiàn),,比如變成了兩條指令,,或者從PC偏移地址讀取一個(gè)32位的數(shù)據(jù)給寄存器。 2) 關(guān)于LDR偽指令,,可以裝載一個(gè)32bit立即數(shù)的說法并不正確,因?yàn)樵趯?shí)際中并不是這一條語句裝載了32bit立即數(shù)(跟上面的貌似一樣,,呵呵~~),,比如: ldr r1,=0x70000000 其實(shí)真正的匯編代碼是將某個(gè)地址的值傳遞給r1,就是說需要一個(gè)地址存放0x70000000這個(gè)立即數(shù),,在反匯編中,, 如果仔細(xì)看會(huì)返現(xiàn),如果這個(gè)立即數(shù)可以用mov指令的表達(dá)形式來表達(dá),,編譯器就直接用mov了~~
ARM匯編中l(wèi)dr偽指令和ldr指令 ARM是RISC結(jié)構(gòu),,數(shù)據(jù)從內(nèi)存到CPU之間的移動(dòng)只能通過L/S指令來完成,也就是ldr/str指令,。比如想把數(shù)據(jù)從內(nèi)存中某處讀取到寄存器中,只能使用ldr比如:
ldr r0, 0x12345678 就是把0x12345678這個(gè)地址中的值存放到r0中,。而mov不能實(shí)現(xiàn)這個(gè)功能,,mov只能在寄存器之間移動(dòng)數(shù)據(jù),或者把立即數(shù)移動(dòng)到寄存器中,,這個(gè)和x86這種CISC架構(gòu)的芯片區(qū)別最大的地方。x86中沒有l(wèi)dr這種指令,,因?yàn)閤86的mov指令可以將數(shù)據(jù)從內(nèi)存中移動(dòng)到寄存器中,。 ldr r0, =0x12345678
這樣,就把0x12345678這個(gè)值寫到r0中了,。所以,,ldr偽指令和mov是比較相似的,。只不過mov指令限制了立即數(shù)的長度為8位,也就是不能超過512,。而ldr偽指令沒有這個(gè)限制,。如果使用ldr偽指令時(shí),后面跟的立即數(shù)沒有超過8位,,那么在實(shí)際匯編的時(shí)候該ldr偽指令是被轉(zhuǎn)換為mov指令的,。 其實(shí)ldr指令可以裝載一個(gè)32bit立即數(shù)的說法并不確切,,因?yàn)閷?shí)際上并不是這一條語句裝載了一個(gè)32bit立即數(shù),真正的匯編代碼是將某個(gè)地址的值傳遞給r1,就是說需要一個(gè)地址存放0x12345678這個(gè)立即數(shù),。而且如果這個(gè)立即數(shù)可以用mov指令的形式來表達(dá),,會(huì)被編譯器實(shí)際用mov來代替比如: ldr r1,=0x10 會(huì)變成 mov r1,#0x10
|
|