【问题标题】:Why I get segmentation fault for psubd xmm, memory?为什么我得到 psubd xmm,内存的分段错误?
【发布时间】:2026-02-25 03:15:02
【问题描述】:

我在bss 中有一个名为LABELX 的标签,我在其中维护了一个64 位地址。在我的代码中是这样介绍的:

.section    .bss
.lcomm LABELX, 16  ### I reserved 128 bit to have the same length as XMMs

在我的代码中,我有一个减法如下:

psubd   LABELX, %xmm11

取值如下:

Value in XMM11 : F7A2D830 ### the higher bits are all zeros.
Value at LABELX: 7FFFF7A2D740

我希望从 XMM11 中减去存储在 LABELX 中的最低 32 位值,并将结果存储在 XMM11 的最低 32 位中。为什么会出现分段错误?

【问题讨论】:

  • LABELX 是否对齐到 16 个字节?
  • 引用manual"对于 .lcomm 指令不接受对齐参数的目标,这是大多数 ELF 目标的情况,.local 指令可用于与 .comm 组合(参见 Comm)来定义对齐的本地公共数据。"

标签: assembly x86-64 gnu-assembler


【解决方案1】:

分段错误是因为 LABELX 未与 16 字节地址对齐。

使用以下代码定义 LABELX:

.local LABELX
.comm LABELX, 16, 16

第二个 16 是对齐要求。可以省略,因为 16 是默认值(“小于等于符号大小的 2 的最大幂,最大为 16”)。在这种情况下,我认为明确对齐要求是一种很好的做法,因为您依赖它。

【讨论】:

  • 值得指出的是,使用.comm / .lcomm,您不需要.section .bss。如果您使用的是.section .bss,则可以使用.p2align 4 / LABELX: .skip 16(或.zero 16 或其他任何发出16字节零的方式)对齐正常方式。