常常会看到arm-linux汇编中有如下的指令:
.align n
它的意义便是使得下面的代码按必定规矩对齐,.align n 指令的对齐值有两种计划,n 或 2^n ,
各种渠道开始的汇编器一般都不是gas,采纳计划1或2的都许多,gas的方针是替代本来的汇编器,
必定要坚持和本来汇编器的兼容,因此在gas中怎么解说 .align指令会显得有些紊乱,原因在于坚持兼容。
arm-linu是依照2^n的计划对齐的,需求阐明的是这个对齐和ld-script里的对齐不同,不是一会事。
下面的英文就不同渠道的对齐进行了阐明:
版别2.11.92.0.12的gas的info(Mandrake 8.2上的)这样说:
The way the required alignment is specified varies from system to system. For the a29k,
hppa, m68k, m88k, w65, sparc, and Hitachi SH, and i386 using ELF format, the first expression
is the alignment request in bytes. For example `.align 8 advances the location counter until
it is a multiple of 8. If the location counter is already a multiple of 8, no change is needed.
For other systems, including the i386 using a.out format, and the arm and strongarm,
it is the number of low-order zero bits the location counter must have after advancement.
For example `.align 3 advances the location counter until it a multiple of 8.
If the location counter is already a multiple of 8, no change is needed.
从这段文字来看,ARM的.align 5便是2的5次方对齐,也便是4字节对齐,经过反汇编也能够看出对齐方法:
.align 5
stmfd sp!, {r0 – r3, lr}
mov r0, ip
ldmfd sp!, {r0 – r3, pc}^
.align 5
stmfd sp!, {r0 – r3, lr}
mov r0, ip
mov ip, r0
ldmfd sp!, {r0 – r3, pc}^
反汇编:
00000000 <.text>:
0: e92d400f stmdb sp!, {r0, r1, r2, r3, lr}
4: e1a0000c mov r0, ip
8: e8fd800f ldmia sp!, {r0, r1, r2, r3, pc}^
…
20: e92d400f stmdb sp!, {r0, r1, r2, r3, lr}
24: e1a0000c mov r0, ip
28: e1a0c000 mov ip, r0
2c: e8fd800f ldmia sp!, {r0, r1, r2, r3, pc}^
30: e1a00000 nop (mov r0,r0)
34: e1a00000 nop (mov r0,r0)
38: e1a00000 nop (mov r0,r0)
3c: e1a00000 nop (mov r0,r0)
一些劝告:
In the future, everytime when you build an elf file, you need meantime created your map file.
And then you will avoid mistakes like this align.
Also, please also pick up some linker script knowlege part. For embedded system,
we frequently play the linker script to tune an image, for example,
align some special section and so on for protection or/and cache purpose.
wish helpful