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

Nir*_*mar 1 linux-kernel

在路径中的linux源代码中出现的head.s文件中arch/i386/kernel/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
Run Code Online (Sandbox Code Playgroud)

Sam*_*nko 5

实际上ALIGN只是一个宏,在include/linux/linkage.h文件中定义:

#ifdef __ASSEMBLY__
#define ALIGN __ALIGN
Run Code Online (Sandbox Code Playgroud)

__ALIGN定义取决于架构.因为x86你有下一个定义(在内核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
Run Code Online (Sandbox Code Playgroud)

所以最后ALIGN宏只是.alignasm指令,它是4或16字节对齐(取决于CONFIG_X86_ALIGNMENT_16选项值).

您可以CONFIG_X86_ALIGNMENT_16arch/i386/config.in文件中找出您的选项值.该值实际上取决于您的处理器系列.


另一个问题是为什么需要这样的对齐.接下来我的理解是.通常CPU只能访问总线上的对齐地址(对于32位总线,地址通常应该对齐4个字节,例如,您可以访问0x0,0x4,0x8地址等,但是您不能访问0x1,0x3地址,因为它会导致总线上的未对齐访问).

但在你的情况下,我认为情况并非如此,并且只是出于性能原因才进行对齐.基本上这种对齐允许CPU 1:更快地获取部分:

ALIGN

1:  movb $1,X86_HARD_MATH
    .byte 0xDB,0xE4
    ret
Run Code Online (Sandbox Code Playgroud)

所以看起来这ALIGN只是一些小的优化.

另见下一主题:

[1] 为什么代码应该与x86上的偶数地址边界对齐?

[2] x86-64汇编的性能优化 - 对齐和分支预测