Нарушение доступа к сборке movdqa

В настоящее время я пытаюсь написать функцию на ассемблере и хочу переместить 128 бит строки, расположенной по адресу памяти, хранящемуся в rdx, в регистр xmm1.

Если я использую movdqa xmm1, [rdx], я получаю исключение нарушения прав доступа при чтении в позиции 0xFFFFFFFFFFFFFFFF.

Если я попытаюсь использовать вместо этого movdqu xmm1, [rdx], я не получу исключение. Проблема в том, что если я использую movdqu, порядок битов инвертируется.

Поэтому я не знаю, почему я получаю исключение при использовании movdqa, но не при использовании movdqu


person Ben    schedule 11.10.2016    source источник
comment
попробуйте выровнять память по 16 байтам (чтобы строка начиналась с адреса, кратного 16)   -  person Alexander Zhak    schedule 11.10.2016
comment
я не знаю точно, что вы имеете в виду, но моя строка имеет длину ровно 16 байт   -  person Ben    schedule 11.10.2016
comment
Если вы не работаете на «голом железе» или в режиме ядра, это не тот адрес, которым вы владеете. Кроме того, он невыровненный. Наконец, это может быть результатом неудачного mmap() (или, не дай Бог, вы назначаете -1 указателю вручную в своем коде).   -  person EOF    schedule 11.10.2016
comment
я передаю строку из c в свою функцию сборки, и если я отлаживаю программу, я могу ввести адрес в rdx вручную, и я вижу свою строку в правильном месте памяти   -  person Ben    schedule 11.10.2016
comment
Если вы ожидаете, что это сработает, вам придется выровнять строку в коде C по 16-байтовой границе (используя атрибут выравнивания __declspec). Однако, если вы хотите выяснить, действительно ли это выравнивание вызывает проблему, попробуйте изменить инструкцию на MOVDQU в качестве теста. О, я вижу, вы сделали это в соответствии с вашим вопросом. Перевернутые байты будут правильными из-за порядка следования байтов. Первый символ должен быть в младшем байте xmm1, а последний байт — в старшем значащем байте xmm1.   -  person Michael Petch    schedule 12.10.2016
comment
Если бы ваши данные были правильно выровнены и вы использовали MOVDQA, байты по-прежнему выглядели бы одинаково в XMM1.   -  person Michael Petch    schedule 12.10.2016
comment
The problem is if i use movdqu, the order of the bits is inverted. Это отдельная проблема. Если бы ваш адрес был выровнен, вы бы получили идентичные результаты от MOVQDU и MOVDQA.   -  person Peter Cordes    schedule 12.10.2016


Ответы (1)


Большая часть этого уже была сказана в комментариях, но позвольте мне подытожить. Есть три проблемы, поднятые вашим кодом/вопросом:

1) MOVDQA требует, чтобы адреса, с которыми он работает ([rdx] в вашем случае), были выровнены по 16-байтовой границе, иначе вызовет нарушение прав доступа. Это то, что вы видите. Выравнивание по 16-байтовой (DQWORD) границе означает, что, используя ваш пример, вы должны читать, например, из. 0xFFFFFFFFFFFFFFF0, а не 0xFFFFFFFFFFFFFFFF, потому что последнее число не делится на 16.

2) Используемый вами адрес 0xFFFFFFFFFFFFFFFF почти наверняка недействителен.

3) При условии, что вы используете MOVDQA для чтения из действительной области памяти, выровненной по 16 байтам, результаты (в xmm1 в вашем случае) будут ИДЕНТИЧНЫ при использовании MOVDQU. Единственная существенная разница между ними заключается в том, что movdqU позволяет читать из памяти Unaligned (отсюда и U), тогда как movdqA требует (16-байт) A-aligned памяти. расположение. (Последний случай часто будет быстрее, но я не думаю, что вам нужно беспокоиться об этом на данном этапе.)

person PhiS    schedule 12.10.2016
comment
Спасибо, ваше право. Если я выровняюсь с __delspec, я смогу использовать MOVDQA. Кроме того, я новичок в сборке, поэтому я не знал, что проблема с обратными битами на самом деле является ожидаемым поведением. - person Ben; 12.10.2016
comment
MOVDQA и MOVDQU имеют одинаковую производительность, если адрес выравнивается во время выполнения, на Nehalem и более новых процессорах. В наши дни они отличаются только своим поведением с невыровненными адресами: либо сбой, либо невыровненная загрузка (которая только медленнее, если пересекает границу строки кеша или, что еще хуже, до Skylake, границу страницы). - person Peter Cordes; 12.10.2016
comment
@ПитерКордес. Спасибо -- Да, поэтому я часто (и я не удосужился перепроверить, правильно ли я запомнил детали). - person PhiS; 12.10.2016