在 Uboot 的 Start.S 中存在以下源碼: ~~~~ .globl _start _start: b start_code ldr pc, _undefined_instruction ldr pc, _software_interrupt ldr pc, _prefetch_abort ...
在 Uboot 的 Start.S 中存在以下源碼:
.globl _start
_start:
b start_code
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq
_undefined_instruction: .word undefined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq: .word irq
_fiq: .word fiq
.balignl 16,0xdeadbeef
那麼這個 .balignl 16,0xdeadbeef (死牛肉) 的作用是什麼呢?我們先從 balignl 這個偽指令說起:
balign 指令格式:
.balign[wl] abs-expr, abs-expr, abs-expr
第一個參數是一個整數的絕對值,表示後面的指令對齊在它的倍數地址上。
第二個參數也是個絕對值讓你指定要填充的指,隨便指定,比如 0x55aa 之類的都可以。此參數可選,如果省略,那麼預設就用 0 來填充了。
第三個參數也是可選的,表示為了對齊,最大隻能跳過多少個位元組;但是如果需要跳過更多的位元組,那麼這裡添加的對齊就無效了。
.balignw 和 .balignl 是 .balign 的變體;它們分別表示填充 2 個位元組 (word) 及填充 4 個位元組 (long) 。
實例分析
我們以下麵的程式為例,來發現 0xdeadbeef 的奧妙。
_start:
b reset
nop
.balignl 16, 0xdeadbeef
reset:
ldr r0, =0x40000000
該程式的反彙編如下:
00000000 <_start>:
0: ea000002 b 10
4: e1a00000 nop ; (mov r0, r0)
8: deadbeef cdple 14, 10, cr11, cr13, cr15, {7}
c: deadbeef cdple 14, 10, cr11, cr13, cr15, {7}
00000010 <reset>:
10: e3a00101 mov r0, #1073741824 ; 0x40000000
14: e1a00000 nop ; (mov r0, r0)
18: e1a00000 nop ; (mov r0, r0)
1c: e1a00000 nop ; (mov r0, r0)
由上可見,填充了 8 個位元組數據,也就是 2 個 0xdeadbeef 。這樣, ld r0, =0x40000000 就對齊到 0x10 地址處,0x10 就是 16。
最後順便看一下第三個參數的應用情況:
假如將上面的程式 .balignl 16, 0xdeadbeef 改為 .balignl 16, 0xdeadbeef, 4 ,那麼反彙編則會看到下麵的結果:
Disassembly of section .text:
00000000 <_start>:
0: ea000000 b 8
4: e1a00000 nop ; (mov r0, r0)
00000008 :
8: e3a00101 mov r0, #1073741824 ; 0x40000000
c: e1a00000 nop ; (mov r0, r0)
如果要以 16 位元組對齊的話需要再填充 8 個位元組,因為指定最大才能跳過 4 個位元組來對齊,所以偽指令無效。
參考自:www.linuxidc.com/Linux/2013-03/81025.htm