Yasm:vmovaps指令导致分段错误 [英] YASM: vmovaps instruction causing segmentation fault

查看:12
本文介绍了Yasm:vmovaps指令导致分段错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题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指令上收到分段错误信号。我已经检查了有关调整的文档,我认为它们都是正确的。不管它有什么价值,我是在i58600K上运行和执行这个程序的。

我也看过这个similar question。然而,我真的不能将他的问题的答案应用到我的问题上(与他的内联汇编有关)。如果有人能参与进来,我将不胜感激!

推荐答案

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++对齐对象的方式,包括自动(堆栈)或动态存储中的数组。

这篇关于Yasm:vmovaps指令导致分段错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆