在路径arch/i386/kernel/head.S
的linux源代码中的head.s文件中,使用了ALIGN
,如下面ret
指令后面给出的代码片段所示。我的问题是这是什么ALIGN
,据我所知,它不是指令,不是汇编指令,那么这是什么以及为什么在这里使用它?
您可以在以下网站获取head.S
的代码:
http://kneuro.net/cgi-bin/lxr/http/source/arch/i386/kernel/head.S?v=2.4.0
路径:arch/i386/kernel/head.S
/*
* We depend on ET to be correct. This checks for 287/387.
*/
check_x87:
movb $0,X86_HARD_MATH
clts
fninit
fstsw %ax
cmpb $0,%al
je 1f
movl %cr0,%eax
xorl $4,%eax
movl %eax,%cr0
ret
ALIGN /* why ALIGN is used and what it is? */
1: movb $1,X86_HARD_MATH
.byte 0xDB,0xE4
ret
答案 0 :(得分:5)
实际上ALIGN
只是一个在include/linux/linkage.h文件中定义的宏:
#ifdef __ASSEMBLY__
#define ALIGN __ALIGN
__ALIGN
定义取决于架构。对于x86
,您在the same file中有下一个定义(在内核2.4中):
#if defined(__i386__) && defined(CONFIG_X86_ALIGNMENT_16)
#define __ALIGN .align 16,0x90
#define __ALIGN_STR ".align 16,0x90"
#else
#define __ALIGN .align 4,0x90
#define __ALIGN_STR ".align 4,0x90"
#endif
所以最后ALIGN
宏只是.align
asm指令,它是4或16字节对齐(取决于CONFIG_X86_ALIGNMENT_16
选项值)。< / p>
您可以从arch/i386/config.in文件中找出CONFIG_X86_ALIGNMENT_16
选项值。该值实际上取决于您的处理器系列。
另一个问题是为什么需要这样的对齐。接下来我的理解是。通常CPU只能访问总线上的对齐地址(对于32位总线,地址通常应该对齐4个字节,例如可以访问0x0,0x4,0x8地址等,但是你无法访问0x1,0x3地址,因为它会导致unaligned access on bus)。
但在你的情况下,我认为情况并非如此,并且只是出于性能原因才进行对齐。基本上这种对齐允许CPU更快地获取1:
部分:
ALIGN
1: movb $1,X86_HARD_MATH
.byte 0xDB,0xE4
ret
所以看起来ALIGN
只是一些小优化。
另见下一主题:
[1] Why should code be aligned to even-address boundaries on x86?
[2] Performance optimisations of x86-64 assembly - Alignment and branch prediction