.align 5的是多少字节对齐
ARM的初学者,在U-Boot的第一阶段的代码start.S会看到如下的代码:
/*
* exception handlers
*/
.align 5
undefined_instruction:
get_bad_stack
bad_save_user_regs
bl do_undefined_instruction
.align 5
software_interrupt:
get_bad_stack
bad_save_user_regs
bl do_software_interrupt
其中的 .align 5是什么意思,可能都知道是对齐的意思,我们经常听说4字节对齐,8字节对齐,这难倒是5字节对齐,还真没有听说有对齐的字节的个数是奇数的。不是这样的,对于ARM来说,是2的5次方个字节对齐,就是32字节对齐。
.align n /* 2的n次方个字节对齐 */
常用的对齐如下:
.align 2 /* 4字节对齐 */
.align 3 /* 8字节对齐 */
下面来个实例具体说明,一个简单的源代码led.s:
.text
.global _start
_start:
.align 5
ldr r0,=0x56000050
.align 5
mov r1,#0x00005500
.align 5
str r1,[r0]
ldr r0,=0x56000054
mov r1,#0x000000a0
str r1,[r0]
main_loop:
b main_loop
通过arm-linux-objdump反汇编,链接地址是0x30000000.
siyunying@ubuntu:~/dev_home/led2$ arm-linux-objdump -d led_elf
led_elf: file format elf32-littlearm
Disassembly of section .text:
30000000 <_start>:
30000000: e59f004c ldr r0, [pc, #76] ; 30000054 <.text+0x54>
...
30000020: e3a01c55 mov r1, #21760 ; 0x5500
...
30000040: e5801000 str r1, [r0]
30000044: e59f000c ldr r0, [pc, #12] ; 30000058 <.text+0x58>
30000048: e3a010a0 mov r1, #160 ; 0xa0
3000004c: e5801000 str r1, [r0]
30000050 <main_loop>:
30000050: eafffffe b 30000050 <main_loop>
现在我们来分析一下,32字节对齐,意味着把地址用二进制的方式查看,最低位是5 个0。
第一个 .align 5
30000000: e59f004c ldr r0, [pc, #76] ; 30000054 <.text+0x54>
0x30000000的二进制是110000000000000000000000000000,最低位是5个0,满足。
第二个 .align 5
30000020: e3a01c55 mov r1, #21760 ; 0x5500
0x30000020的二进制是110000000000000000000000100000,最低位是5个0,满足。
第三个 .align 5
30000040: e5801000 str r1, [r0]
0x30000020的二进制是110000000000000000000001000000,最低位是5个0,满足。
没有 .align 5
30000044: e59f000c ldr r0, [pc, #12] ; 30000058 <.text+0x58>
30000048: e3a010a0 mov r1, #160 ; 0xa0
3000004c: e5801000 str r1, [r0]
这些地址就按4个字节增加,因为一条ARM指令是4个字节。