【问题标题】:YASM: vmovaps instruction causing segmentation faultYASM:导致分段错误的 vmovaps 指令
【发布时间】:2019-02-05 22:31:52
【问题描述】:

问题movaps 给我一个分段错误。

上下文:x86-64 指令vmovaps 设计用于Core i 系列处理器(我正在运行此系统)上的AVX 寄存器。 AVX 寄存器的宽度是 SSE 寄存器的两倍(分别为 256 位和 128 位)。指令vmovaps 应将对齐的浮点值(32 位)向量移动到指定的ymm 寄存器中。

可能的原因:源数据的对齐特别重要,因为不正确对齐的数据是分段错误的根源。然而,即使我已经对齐了我的数据,我自己也遇到了分段错误。

示例

    segment .data

align 16
xs:
    dd  0.0
    dd  1.1
    dd  2.2
    dd  3.3
    dd  4.4
    dd  5.5
    dd  6.6
    dd  7.7

align 16
ys:
    dd  8.8
    dd  7.7
    dd  6.6
    dd  5.5
    dd  4.4
    dd  3.3
    dd  2.2
    dd  1.1

    segment .text
    global main

main:
    push rbp
    mov rbp, rsp

    ; Move eight 32-bit floats from "xs" into ymm0
    vmovaps ymm0, [xs]

    ; Move eight 32-bit floats from "ys" into ymm1
    vmovaps ymm1, [ys]

    ; Add all eight to each other simulatenously, put in ymm0
    vaddps ymm0, ymm1

    xor rax, rax
    leave
    ret

编译于yasm -f elf64 -g dwarf2 <filename>

链接到gcc -o <bin-name> <filename>.o

当我使用 GDB 运行它时,它只是报告它在第一条 vmovaps 指令上收到了分段错误信号。我检查了有关对齐的文档,我认为这一切都是正确的。对于它的价值,我正在 i5 8600K 上运行和执行它。

我也看过这个similar question。但是我不能真正将他的问题的答案应用于我的问题(与他的内联汇编有关)。如果有人可以对此进行权衡,我将不胜感激!

【问题讨论】:

  • 好吧,既然你已经在你的调试器中,那么你看看实际地址来验证它是否对齐如何?您确实意识到使用 ymm0 意味着您必须有 32 字节对齐,对吧?所以你应该改成align 32。手册上说得很清楚:“当源或目的操作数是内存操作数时,操作数必须在16字节(128位版本)、32字节(VEX.256编码版本)上对齐”
  • @Jester 我正在使用由 Rey Sethfa​​rth 编写的指南。我相信他的话,但他提到需要 16 字节对齐。我看到他没有具体说明什么......(FWIW 它们在 GDB 中是 16 字节对齐的。但不是 32)
  • @Jester 这正是问题所在。对不起,我没有 RTFM。我只是有点坚持我正在阅读的这本书,并坚持我从中获得的信息。如果你把它写成答案,我会接受。

标签: assembly x86-64 nasm memory-alignment avx


【解决方案1】:

vmovapsymm0 操作数需要 32 字节对齐。引用the manual:

当源或目标操作数是内存操作数时, 操作数必须在 16 字节(128 位版本)上对齐,32 字节 (VEX.256 编码版本) 或 64 字节(EVEX.512 编码版本) 将生成边界或一般保护异常 (#GP)。 对于 EVEX.512 编码版本,操作数必须与大小对齐 内存操作数。

(强调添加)。 Linux 将 SIGSEGV 传递给导致#GP 异常的进程。

因此,对于 dd 元素的静态数组,您应该将 align 16 更改为 align 32

或者使用vmovups未对齐加载,让硬件处理;在恰好对齐的数据上具有相同的速度,并且在大多数 CPU 上,对于不跨越缓存线边界的加载/存储也是如此。

相关:How to solve the 32-byte-alignment issue for AVX load/store operations? 用于 C 和 C++ 对齐事物的方式,包括自动(堆栈)或动态存储中的数组。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-25
    • 1970-01-01
    • 2021-03-02
    相关资源
    最近更新 更多