linux源代码中的arch / i386 / kernel / head.S中的ALIGN是什么

时间:2015-10-11 16:51:49

标签: linux-kernel

在路径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

1 个答案:

答案 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