【问题标题】:FASM align 32 section is not aligned enoughFASM align 32 部分对齐不够
【发布时间】:2020-01-29 00:55:24
【问题描述】:

我正在使用 FASM,这是我的程序

format ELF64

section '.text' executable

public func

func:
        vmovaps ymm0, YWORD [.table]
        xor     rax, rax
        ret

        align 32
        .table:
                DQ      1024
                DQ      1024
                DQ      1024
                DQ      1024
                DQ      2048
                DQ      2048
                DQ      2048
                DQ      2048

我使用 AVX,所以我创建了一个表(必须在 32 字节边界对齐) 初始化 ymm0 寄存器。 但是当我尝试编译这个程序时,我从 FASM 收到“section is notaligned enough”错误。 “.table”必须在 32 字节边界对齐,因为我使用的是“movaps”(或 movdqa(无论如何))。但为什么 FASM 给我一个错误? 像这样使用'align'有错吗?

更新 做这样的事情是否正确?因为这样做,程序运行没有任何问题,但它是正确的方式吗?

section '.text' executable

public func

func:
        vmovaps ymm0, YWORD [.table]
        xor     rax, rax
        ret

        section '.rodata' align 32

        .table:
                DQ      1024
                DQ      1024
                DQ      1024
                DQ      1024
                DQ      2048
                DQ      2048
                DQ      2048
                DQ      2048

【问题讨论】:

  • 请注意,将数据放在代码旁边几乎没有什么好处。 x86 CPU 使用拆分 I/D L1 高速缓存和拆分 iTLB / dTLB。 (但统一了 L2 数据和 L2TLB)。通常最好将所有常量组合在一起,以避免数据污染 I-cache,反之亦然;这就是为什么section .rodata 是一回事。此外,对于 AVX / AVX2,您可以使用 vpbroadcastqvbroadcastsd 加载,因此您只需要一个 dq 1024 来填充寄存器。如果您无论如何要将它们加载到寄存器中,这可以让您免费“压缩”常量,除非它不适用于 vpaddq ymm0, [mem] 例如
  • 谢谢人...好点...
  • 但是有一点......将表格放在每个函数的末尾,我们的最终文件将太大!对吗?
  • 一般来说,您不想复制常量,即使它们很小。虽然我猜如果这意味着函数的所有常量都在同一个缓存行中,那么重复一个标量浮点数或双精度数是有意义的。 (而不是从常量附近的一个单独位置加载一个常量,用于另一个函数,它只共享一个小常量。)无论如何,避免重复是一个单独的问题,而不是将所有rodata 组合到一个部分中。你想两者都做。
  • @PeterCordes 对于重复使用的常量,有一个特殊的 ELF 功能可以在适当的部分合并相等的常量。

标签: assembly x86 sse memory-alignment fasm


【解决方案1】:

使用 FASM,节内的对齐不能大于节本身的对齐。当您不指定节的对齐方式时,ELF64 的默认值为 8,ELF 的默认值为 4。要更改默认部分对齐方式,请使用 align,如下所示:

section '.text' executable align 32

这应该允许您在该部分中使用最多 32 个对齐。您的代码可能看起来像这样:

section '.text' executable align 32

public func
public func2

func:
        vmovaps ymm0, YWORD [.table]
        xor     rax, rax
        ret

        align 32
        .table:
                DQ      1024
                DQ      1024
                DQ      1024
                DQ      1024
                DQ      2048
                DQ      2048
                DQ      2048
                DQ      2048

func2:
        vmovaps ymm0, YWORD [.table]
        xor     rax, rax
        ret

        align 32
        .table:
                DQ      1024
                DQ      1024
                DQ      1024
                DQ      1024
                DQ      2048
                DQ      2048
                DQ      2048
                DQ      2048

您可以将.rodata(只读)中的常量数据与.text(代码)部分中的代码分开。您可以使用该数据拥有多个功能。您可以放置​​不同的表和数据,并在部分内使用align 指令来对齐可能需要它的特定数据。这段代码没有做任何有用的事情,只是一个例子:

FORMAT ELF64

section '.text' executable

public func
public func2
public func3
public func4

func:
        vmovaps ymm0, YWORD [table]
        xor     rax, rax
        ret

func2:
        vmovaps ymm0, YWORD [table2]
        mov     eax, MyStr
        ret

func3:
        vmovaps ymm0, YWORD [table]
        xor     rax, rax
        ret

func4:
        vmovaps ymm0, YWORD [table3]
        xor     rax, rax

        ret

section '.rodata' align 32

MyStr: DB 'Hello There', 0

align 32
table:
        DQ      1024
        DQ      1024
        DQ      1024
        DQ      1024
        DQ      2048
        DQ      2048
        DQ      2048
        DQ      2048

align 32
table2:
        DQ      1024
        DQ      1024
        DQ      1024
        DQ      1024
        DQ      2048
        DQ      2048
        DQ      2048
        DQ      2048

table3:
        DQ      1024
        DQ      1024
        DQ      1024
        DQ      1024
        DQ      2048
        DQ      2048
        DQ      2048
        DQ      2048

注意:在此示例中,所有表格数据都是相同的,但在实际情况下,表格将具有您需要的任何相关值。

【讨论】:

  • @jason:在您的更新中可以使用,但是假设您在 .rodata 中有其他数据,然后需要其他对齐方式,您仍然可以在部分中使用 align 直到对齐部分本身。我已经用另一种更接近你原来的方式更新了我的答案。
  • thx ...一个问题...如果我在我的文本部分使用 align 32,它是否会使我的程序更大(大小)?例如,我可能有超过 20 个函数,其中只有一个使用 32 字节对齐 .... 最好对所有函数使用一个“section '.text' executable align 32” header,或者最好使用“section '.text 'executable align 32" 用于需要 align 32 的函数并使用“section '.text' executable” header 用于其他函数(不需要 align 32)?
  • 对于您的最后一次更新...。我认为最好将每个表放在我们想要使用它的函数的末尾...所以我认为列出是个坏主意“rodata”中的所有表,最好在函数末尾定义表......对吗?
  • @jason:如果您查看更新,我提供了两个版本,一个是表在函数中,另一个是表在 .rodata` 中。我们的想法是,如果您愿意,可以在单独的部分中向您展示如何操作。
  • 是的,谢谢......但问题是哪一个?哪个更好用? (如果我们有大量的函数和大量的表......)
猜你喜欢
  • 2020-02-03
  • 2021-05-02
  • 2015-04-04
  • 2021-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-18
  • 2017-10-13
相关资源
最近更新 更多