首先要弄明白.balignl的意思,這個其實應該算是一個僞操作符,僞操作符的意思就是機器碼裏,並沒有一個彙編指令與其對應,是編譯器來實現其功能的。.balignl是.balign的變體。
.balign是意思是,以當前地址開始,以第一個參數爲整數倍的地址爲尾,1個字節1字節的填充第二個參數值(第二個參數也是1個字節的值)。
.balign 8, 0xde
解釋:以當前地址開始,逐字節的往地址單元中填入0xde值,直到遇到第一個地址爲8的倍數。如果當前地址(pc值)正好是8的倍數,則沒有東西被寫入到內存。
那麼以此類推,.balignw則表示逐半字(2個字節)的填充,第二個參數是2個字節的值,所以一般有這樣的形式出現:
.balignw 4,0x368d
因爲現在填入的內容爲16位了,那就存在以下幾種情況
1.當前地址沒有偏移就滿足了以4爲倍數的地址
2.當前地址偏移了1個字節就滿足了要求
3.當前地址偏移了2個字節就滿足了要求
4.當然地址編移了3個字節就滿足了要求
當沒有偏移的時候,地址中間肯定沒有辦法填上信息;
當偏移1個字節的時候,地址中間空隙不夠,所以填入的數值,是末定義,也就是說,填入的什麼值,不清楚;
當偏移爲2個字節的時候,地址中間的空隙正好填入手面的數據,所以就填上了;
當偏移爲3個字節的時候,地址中間的空隙大於所要填的內容。手冊上給的定義是末定義,在我的理解,其實這個未定義,是指這三個偏移的地址整體的內容是末知的。但是其中必定含有要填的2個字節,只是另一個被填充的字節內容不知道而已
所以以此類推,就知道.balignl的作用了。
在u-boot的start.S彙編代碼中最下面一條對齊指令:
.globl _start //u-boot啓動入口
_start: b
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
其中:
.globl _start //不佔內存
_start: b start_code //佔4字節內存
ldr pc, _undefined_instruction //佔4字節內存
ldr pc, _software_interrupt //佔4字節內存
ldr pc, _prefetch_abort //佔4字節內存
ldr pc, _data_abort //佔4字節內存
ldr pc, _not_used //佔4字節內存
ldr pc, _irq //佔4字節內存
ldr pc, _fiq //佔4字節內存
佔了4x8=32字節內存。
_undefined_instruction: .word undefined_instruction //佔4字節內存
_software_interrupt: .word software_interrupt //佔4字節內存
_prefetch_abort: .word prefetch_abort //佔4字節內存
_data_abort: .word data_abort //佔4字節內存
_not_used: .word not_used //佔4字節內存
_irq: .word irq //佔4字節內存
_fiq: .word fiq //佔4字節內存
佔了4x7=28字節內存。
所以在這個.balignl 16,0xdeadbeef指令之前,一共佔了32+28=60bytes的內存,用.balignl 16,0xdeadbeef在地址60後填充4個字節的數據(0xdeadbeef),把當前指針往後移到地址爲64的位置,起到對齊的作用!
補充:
.balignl 完整指令格式爲:
.balignl {alignment} {,fill} {,max}。
第一個參數alignment爲一個正整數,以alignment的值的整數倍爲結束地址進行對齊,以當前地址爲起始地址,進行字節填充,比如當前地址爲20,而alignment的值我們設定爲16,那麼字節填充自20開始,結束於20後第一個16的倍數地址處,即32處。
第二個參數fill即我們選定的,用來填充的數值。balignl模式下爲4字節,不夠4字節系統會自動補夠4字節,此參數可選,不標則採用默認值0。
第三個參數max也是可選項,默認值爲alignment。若對齊時偏移量大於max,則不偏移。同上例,從16--32,偏移量爲16,如果max我們設置爲8,那麼該偏移不進行。
參考:https://www.xuebuyuan.com/3121739.html