align 的用法(u-boot源代码分析)
生活随笔
收集整理的這篇文章主要介紹了
align 的用法(u-boot源代码分析)
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
今決定認(rèn)真分析一下u-boot的代碼,但一開(kāi)始就被“.balignl 16 0xdeadbeef”這條語(yǔ)句難住了,還好,google了一下,找到了《分析了一下 align 的用法》這篇文章,作者寫得很好,看完后,我根據(jù)自己的實(shí)驗(yàn)結(jié)果,做了適當(dāng)?shù)母?#xff0c;以讓自己看起來(lái)更明白,把它記錄如下: .align 就是用來(lái)對(duì)齊的,究竟怎么對(duì)齊,有啥情況?下面分析一下 (一) $vim align1.s 在新建的文件編輯以下代碼: _start:
??? b reset
??? .byte 0x55
??? .byte 0xaa
reset:
??? ldr r0, =0x53000000 保存后,執(zhí)行如下命令: $arm-linux-as align1.s -o align1.o 這樣的話有的編譯器可能會(huì)報(bào)錯(cuò),但我的編譯器沒(méi)有報(bào)錯(cuò),雖然沒(méi)有報(bào)錯(cuò),但反匯編的結(jié)果顯示,運(yùn)行時(shí)肯定會(huì)出問(wèn)題。 執(zhí)行如下命令: $arm-linux-objdump -d align1.o 顯示如下: ?00000000 <_start>:
?? 0: ea000000? b??4? <_start+0x4>
?? 4: 0453aa55? ldreqb s1, [r3], -#2645 00000006 <reset>:
?? 6: e3a00453? mov r0, #1392508928 ; 0x53000000 很明顯,跳轉(zhuǎn)語(yǔ)句應(yīng)該跳到0x06處,而它卻跳到0x04處,我們分析一下。首先,ARM指令都是32位的,這里要求4字節(jié)(一個(gè)word)對(duì) 齊,b reset 指令占了4個(gè)字節(jié),接著我們用 .byte 指令定義2個(gè)常數(shù),因?yàn)檫@里是 byte 類型,所以只占了八位,兩個(gè)數(shù)據(jù),一共占16位。由于連接器內(nèi)部有一個(gè)程序地址計(jì)數(shù)指針,里面保存著當(dāng)前的地址,這地址指針是連接器內(nèi)部工作需要的,我們 不需要理會(huì),只需要了解有這么一個(gè)機(jī)制。假如_start從0x00,第一條指令占4個(gè)byte,然后連續(xù)分配2個(gè)byte,當(dāng)前地址指針應(yīng)該是 0x06,那么問(wèn)題來(lái)了,下條指令,也就是標(biāo)號(hào) reset 處的ldr指令,是一條ARM指令,這要求是 4個(gè)字節(jié)對(duì)齊的,當(dāng)前的地址為 0x06,并不能滿足這個(gè)要求,所以編譯器自動(dòng)將地址指針跳到0x04。 解決辦法很簡(jiǎn)單,我們只需要加一條 .align 指令,問(wèn)題就解決了 _start:
??? b reset
??? .byte 0x55
??? .byte 0xaa
??? .align
reset:
??? ldr r0, =0x53000000 編譯結(jié)果是: 00000000 <_start>:
?? 0: ea000000? b 8 <reset>
?? 4: 0000aa55? andeq sl, r0, r5, asr sl 00000008 <reset>:
?? 8: e3a00453? mov r0, #1392508928 ; 0x53000000 在兩個(gè) .byte 指令后自動(dòng)補(bǔ)零,直到滿足地址要求為止。這里就是將地址累加到 0x08符合ARM指令要求,所以在這里寫入下條指令。這是基本內(nèi)容,下面研究一下其他 (二).align 5 這里只是一個(gè)例子,重點(diǎn)想說(shuō)的是 這個(gè) .align 5 后面的 5 究竟是什么意思? uboot里面就有這指令。我們繼續(xù)做做試驗(yàn),看看編譯結(jié)果是什么 _start:
??? b reset
???
??? .align 5
??? .byte 0x55
???
??? .align 5
??? .byte 0xaa
???
??? .align
reset:
??? ldr r0, =0x53000000 編譯結(jié)果: 00000000 <_start>:
?? 0: ea00000f? b 44 <reset>
?...
? 20: 00000055? andeq r0, r0, r5, asr r0
?...
? 40: 000000aa? andeq r0, r0, sl, lsr #1 00000044 <reset>:
? 44: e3a00453? mov r0, #1392508928 ; 0x53000000 我們發(fā)現(xiàn)這編譯結(jié)果有點(diǎn)意思,這地址分配一下子上去了,但是也不難,分析一下就OK,看那個(gè) 20 和 40 ,這里是十六進(jìn)制,也就是 32 和 64了。那么很容易可以聯(lián)想到,這里做的是冪運(yùn)算,也就是 .align 5 對(duì)齊的地址為 2^5 = 32,之前的地址全部補(bǔ)零。 (三).balignl 16,0xdeadbeef _start:
??? b reset
???
??? .balignl 16,0xdeadbeef
???
reset:
??? ldr r0, =0x53000000 在看uboot的時(shí)候還有這么一個(gè)語(yǔ)句,查了半天as的手冊(cè)才找到,囧,不過(guò)稍微做了一下實(shí)現(xiàn),覺(jué)得又不是很難,我們看看結(jié)果: 00000000 <_start>:
?? 0: ea000002? b 10 <reset>
?? 4: deadbeef? cdple 14, 10, cr11, cr13, cr15, {7}
?? 8: deadbeef? cdple 14, 10, cr11, cr13, cr15, {7}
?? c: deadbeef? cdple 14, 10, cr11, cr13, cr15, {7} 00000010 <reset>:
? 10: e3a00453? mov r0, #1392508928 ; 0x53000000 可以看出,這指令就是將 deadbeef字符串填進(jìn)去,一共填到地址為16對(duì)齊的地方為指,上面可以看到,這里填到 0x10 也就是 16了。 轉(zhuǎn)自:http://blogold.chinaunix.net/u3/94328/showart_1917728.html
??? b reset
??? .byte 0x55
??? .byte 0xaa
reset:
??? ldr r0, =0x53000000 保存后,執(zhí)行如下命令: $arm-linux-as align1.s -o align1.o 這樣的話有的編譯器可能會(huì)報(bào)錯(cuò),但我的編譯器沒(méi)有報(bào)錯(cuò),雖然沒(méi)有報(bào)錯(cuò),但反匯編的結(jié)果顯示,運(yùn)行時(shí)肯定會(huì)出問(wèn)題。 執(zhí)行如下命令: $arm-linux-objdump -d align1.o 顯示如下: ?00000000 <_start>:
?? 0: ea000000? b??4? <_start+0x4>
?? 4: 0453aa55? ldreqb s1, [r3], -#2645 00000006 <reset>:
?? 6: e3a00453? mov r0, #1392508928 ; 0x53000000 很明顯,跳轉(zhuǎn)語(yǔ)句應(yīng)該跳到0x06處,而它卻跳到0x04處,我們分析一下。首先,ARM指令都是32位的,這里要求4字節(jié)(一個(gè)word)對(duì) 齊,b reset 指令占了4個(gè)字節(jié),接著我們用 .byte 指令定義2個(gè)常數(shù),因?yàn)檫@里是 byte 類型,所以只占了八位,兩個(gè)數(shù)據(jù),一共占16位。由于連接器內(nèi)部有一個(gè)程序地址計(jì)數(shù)指針,里面保存著當(dāng)前的地址,這地址指針是連接器內(nèi)部工作需要的,我們 不需要理會(huì),只需要了解有這么一個(gè)機(jī)制。假如_start從0x00,第一條指令占4個(gè)byte,然后連續(xù)分配2個(gè)byte,當(dāng)前地址指針應(yīng)該是 0x06,那么問(wèn)題來(lái)了,下條指令,也就是標(biāo)號(hào) reset 處的ldr指令,是一條ARM指令,這要求是 4個(gè)字節(jié)對(duì)齊的,當(dāng)前的地址為 0x06,并不能滿足這個(gè)要求,所以編譯器自動(dòng)將地址指針跳到0x04。 解決辦法很簡(jiǎn)單,我們只需要加一條 .align 指令,問(wèn)題就解決了 _start:
??? b reset
??? .byte 0x55
??? .byte 0xaa
??? .align
reset:
??? ldr r0, =0x53000000 編譯結(jié)果是: 00000000 <_start>:
?? 0: ea000000? b 8 <reset>
?? 4: 0000aa55? andeq sl, r0, r5, asr sl 00000008 <reset>:
?? 8: e3a00453? mov r0, #1392508928 ; 0x53000000 在兩個(gè) .byte 指令后自動(dòng)補(bǔ)零,直到滿足地址要求為止。這里就是將地址累加到 0x08符合ARM指令要求,所以在這里寫入下條指令。這是基本內(nèi)容,下面研究一下其他 (二).align 5 這里只是一個(gè)例子,重點(diǎn)想說(shuō)的是 這個(gè) .align 5 后面的 5 究竟是什么意思? uboot里面就有這指令。我們繼續(xù)做做試驗(yàn),看看編譯結(jié)果是什么 _start:
??? b reset
???
??? .align 5
??? .byte 0x55
???
??? .align 5
??? .byte 0xaa
???
??? .align
reset:
??? ldr r0, =0x53000000 編譯結(jié)果: 00000000 <_start>:
?? 0: ea00000f? b 44 <reset>
?...
? 20: 00000055? andeq r0, r0, r5, asr r0
?...
? 40: 000000aa? andeq r0, r0, sl, lsr #1 00000044 <reset>:
? 44: e3a00453? mov r0, #1392508928 ; 0x53000000 我們發(fā)現(xiàn)這編譯結(jié)果有點(diǎn)意思,這地址分配一下子上去了,但是也不難,分析一下就OK,看那個(gè) 20 和 40 ,這里是十六進(jìn)制,也就是 32 和 64了。那么很容易可以聯(lián)想到,這里做的是冪運(yùn)算,也就是 .align 5 對(duì)齊的地址為 2^5 = 32,之前的地址全部補(bǔ)零。 (三).balignl 16,0xdeadbeef _start:
??? b reset
???
??? .balignl 16,0xdeadbeef
???
reset:
??? ldr r0, =0x53000000 在看uboot的時(shí)候還有這么一個(gè)語(yǔ)句,查了半天as的手冊(cè)才找到,囧,不過(guò)稍微做了一下實(shí)現(xiàn),覺(jué)得又不是很難,我們看看結(jié)果: 00000000 <_start>:
?? 0: ea000002? b 10 <reset>
?? 4: deadbeef? cdple 14, 10, cr11, cr13, cr15, {7}
?? 8: deadbeef? cdple 14, 10, cr11, cr13, cr15, {7}
?? c: deadbeef? cdple 14, 10, cr11, cr13, cr15, {7} 00000010 <reset>:
? 10: e3a00453? mov r0, #1392508928 ; 0x53000000 可以看出,這指令就是將 deadbeef字符串填進(jìn)去,一共填到地址為16對(duì)齊的地方為指,上面可以看到,這里填到 0x10 也就是 16了。 轉(zhuǎn)自:http://blogold.chinaunix.net/u3/94328/showart_1917728.html
轉(zhuǎn)載于:https://www.cnblogs.com/hnrainll/archive/2011/06/14/2080243.html
總結(jié)
以上是生活随笔為你收集整理的align 的用法(u-boot源代码分析)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 使用Mybatis Generator自
- 下一篇: 2440之中断管理