В x64, используя «pop [RAX]», где значение временно сохраняется? - PullRequest
2 голосов
/ 19 сентября 2019

Я нашел ответы, объясняющие, что прямое копирование из памяти в память невозможно на платформах x86 без сохранения значения где-то посередине.

mov rax,[RSI]
mov [RDI],rax

Я интенсивно использую 64-битные записи в память, используяpop, который, по-видимому, копирует значения из памяти и в память напрямую, без какого-либо видимого «посредника».

Где находится значение до его записи, но после того, как оно было прочитано?

Ответы [ 2 ]

5 голосов
/ 19 сентября 2019

Временное расположение - это буфер где-то внутри ЦП, который не является частью архитектурного состояния.

На современном x86, таком как Skylake, pop [mem] декодируется как 2 мопа, поэтому, вероятно, первый мопpop во внутренний регистр, а второй - хранилище.

Мы знаем, что современные процессоры x86 имеют несколько дополнительных логических регистров, зарезервированных для использования микрокодом и многопользовательскими инструкциями, подобными этим.Они переименовываются в физический регистровый файл так же, как архитектурные регистры.Например, http://blog.stuffedcow.net/2013/05/measuring-rob-capacity/ упоминает "некоторые дополнительные архитектурные регистры для внутреннего использования".Генри называет их «архитектурными» регистрами, но это может ввести в заблуждение терминологию.Он просто означает логический, а не физический, как архитектурный регистр.Эти временные регистры (AFAIK) не используются за границами инструкций, только в пределах одной инструкции x86.

Исходный код 8086 не был конвейерным (кроме предварительной выборки инструкций), поэтому внутренний микрокод или логика, которые реализовали pop [mem], предположительнотолько что загружен, а затем сохранен из какого-то специального буфера.Как add [mem], reg, но с другим адресом для загрузки и хранилища и без подачи его через ALU.

прямое копирование из памяти в память невозможно на x86.

Вы, вероятно, имеете в виду такие вещи, как принятый ответ на Почему IA32 не позволяет памяти в память mov? Это объяснение причины, к сожалению, просто неверно и очень вводит в заблуждение.

Это инструкция ограничение кодировки , которое делает невозможным mov [mem], [mem], а не ограничение внутренних компонентов ЦП.См. Какие инструкции x86 принимают два (или более) операнда памяти?
pop [mem] - один из них, потому что один из операндов памяти неявный .Даже оригинальный 8086 мог сделать это.


Я интенсивно использую 64-битные записи в память, используя pop

Если пропускная способность переднего плана или порт 2/3давление является узким местом, рассмотрите возможность использования 128-битных загрузок SSE из стека, а затем сохраните 64-битные половины с movlps и movhps.На современных процессорах Intel (например, Skylake) movhps [mem], xmm0 - это команда с одним битом.(На самом деле микроплавление; все хранилища являются адресом магазина + данными магазина. Но в любом случае, порт 5 не должен перемешивать, как для бесполезной формы назначения памяти pextrq).

Или, если ваши пункты назначенияявляются смежными, делают 128-битные или 256-битные копии.

Есть варианты использования для pop [mem], но это не удивительно, и, как правило, не быстрее в Intel, чем pop reg / mov [mem], reg, потому что этоеще 2 моп.Он обеспечивает безопасный размер кода и не требует регистра tmp.

См. https://agner.org/optimize/

3 голосов
/ 19 сентября 2019

pop [rax] - это один из способов выполнить операцию «память в память».Значение popped, вероятно, хранится где-то посередине, но это деталь реализации.Под этими ответами подразумевается, что инструкции, использующие байт modr / m для своих операндов, могут иметь не более одного операнда памяти.Это большинство инструкций, но не такие, как movsb [rdi], [rsi], у которых встроенные операнды встроены в инструкцию.

...