【问题标题】:When does a quadword (NASM DQ) need to be 16-byte aligned?四字 (NASM DQ) 何时需要 16 字节对齐?
【发布时间】:2020-07-11 18:21:24
【问题描述】:

根据 Intel 64 和 IA-32 架构软件开发人员手册合卷(2019 年 10 月)第 4.1.1 节“字、双字、四字和双四字的对齐方式”:

"字、双字和四字在内存中不需要在自然边界上对齐。字、双字和四字的自然边界是偶数地址、可被四整除的地址、可被四整除的地址分别是八个。”

但是手册后面的一段说:

“某些对双四字进行操作的指令要求内存操作数在自然边界上对齐。如果指定了未对齐的操作数,这些指令会生成通用保护异常 (#GP)。双四字的自然边界是任意地址能被 16 整除。”

我只是将我的数据部分安排在 64 字节边界上对齐,并将所有 dq 变量组织在一起以设置在单个缓存行上。以下是前八个 dq:

section .data align=64
Return_Pointer_Array: dq 0, 0, 0
data_master_ptr: dq 0
n_ptr: dq 0
n_ctr: dq 0
n_length: dq 0
collect_ptr: dq 0

数据部分比这大,但我通过 Agner Fog 的 objconv 运行它,他没有显示数据对齐问题 - 在早期的工作中,我发现如果存在对齐问题,Fog 的 objconv 会标记它们。

我的问题是:如英特尔在上面引用的最后一段中所说,在什么情况下我必须将每个 dq 对齐到一个可被 16 整除的地址上?什么指令会导致这样的要求?

【问题讨论】:

  • 任何对 XMM 寄存器进行操作的 SIMD 指令都需要在 16 字节对齐的边界上对齐。需要对齐访问的说明,例如 felixcloutier.com/x86/movdqa:vmovdqa32:vmovdqa64
  • 您的示例中有一个严重错误:DQ is QuadWord = 8 bytes。您在谈论DDQ,即 DoubleQuadWord = 16 字节。所以 16 个字节是 DDQ 值的 自然 边界。
  • 你的标题是“双四字”,即DDQ。 (我知道这是违反直觉的),我用this answer 进行了检查。
  • @zx485 :如果人们理解第一个 D 意味着 Define,他们可能不会觉得它违反直觉
  • 现在,在您编辑之后,这个问题没有任何意义:您引用了“单词、双字和四字不需要在内存中的自然边界上对齐。”因此,根据英特尔手册,DQ 不需要在 16 字节边界上对齐。但是你的标题会问它是否......

标签: assembly optimization x86-64 nasm


【解决方案1】:

例如MOVAPD(内存地址必须对齐)和MOVUPD(内存地址不必对齐)

【讨论】:

  • 您的意思是 MOVAPD 要求 8 字节 (DQ) 操作数需要 16 字节对齐?
  • @RTC222 MOVAPD 不采用 8 字节操作数。如果你给它一个内存地址,它会从中读取 16 个字节。
  • 是的。 MOVAPD 表示“移动 对齐 压缩双精度浮点值”。要获取未对齐的值,请使用 MOVUPD 版本,这意味着“移动 未对齐 压缩双精度浮点值”。两者都移动 16 字节双四字值。
  • 因此 MOVAPD 使用 16 字节对齐。我从我的问题中看到了困惑。第二段指的是 DDQ,它是 128 字节,所以必须是 16 字节对齐的。我的困惑是由于 NASM 对 8 字节使用 dq(看起来像双四字)。如果是 DDQ 则 16 字节对齐。
【解决方案2】:

此答案由@RTC222(OP)提供,作为他们自己问题的解决方案:

英特尔手册显示四字(NASM dq - 8 字节)必须是 8 字节对齐的。双四字(NASM ddq - 16 字节)必须是 16 字节对齐的。我的问题是由于将 dq 误读为“双四字”,而它的意思是“定义四字”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 2016-12-19
    • 1970-01-01
    • 1970-01-01
    • 2020-12-05
    相关资源
    最近更新 更多