YASM: инструкция vmovaps, вызывающая ошибку сегментации - PullRequest
0 голосов
/ 06 февраля 2019

Проблема : movaps вызывает ошибку сегментации.

Контекст : Инструкция x86-64 vmovaps предназначена для использования с регистрами AVX на процессоре серии Core i (с которым я работаю в этой системе).Регистры 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.

Я также посмотрел на этот похожий вопрос .Однако я не могу действительно применить ответ к его проблеме к моей (что-то связанное с его встроенной сборкой).Если бы кто-то мог оценить это, я был бы признателен!

1 Ответ

0 голосов
/ 06 февраля 2019

vmovaps с операндом ymm0 требует выравнивания 32 байтов.Цитируем руководство:

Когда операндом источника или назначения является операнд памяти, операнд должен быть выровнен по 16-байтной (128-битной версии), 32-байтной (VEX).256 кодированная версия) или 64-байтовая (кодированная версия EVEX.512) граница или исключение общей защиты (#GP).Для версий с кодировкой EVEX.512 операнд должен быть выровнен по размеру операнда памяти.

(выделение добавлено)

Таким образом, вы должны изменить align 16 на align 32.

...