В архитектуре Intel IA32 инструкции, такие как movl, movw, не позволяют использовать операнды, которые являются одновременно ячейками памяти. Например, инструкция movl (% eax), (% edx) не разрешена. Почему?
Почему IA32 не позволяет памяти памяти mov?
Ответ 1
Ответ включает в себя более полное понимание ОЗУ. Проще говоря, ОЗУ может находиться только в двух состояниях, режиме чтения или режиме записи. Если вы хотите скопировать один байт в ram в другое место, вы должны иметь временную область хранения вне RAM при переключении с чтения на запись.
Конечно, архитектура может иметь такую оперативную память для ОЗУ, но это будет команда высокого уровня, которая в микрокоде будет переводить на копирование данных из ОЗУ в регистр, а затем обратно в ОЗУ. В качестве альтернативы, можно было бы расширить контроллер RAM, чтобы иметь такой временный регистр только для этого копирования данных, но это не принесло бы большой пользы для дополнительной сложности взаимодействия CPU/Hardware.
EDIT: Стоит отметить, что последние достижения, такие как гибридный куб памяти и память с высокой пропускной способностью, представляют собой архитектуры, в которых топология ОЗУ стала больше похожей на PCI-e и прямую оперативную память на RAM-передачи возможно, но это связано с логикой поддержки технологий, а не с самой ОЗУ. В архитектуре ЦП это было бы в виде огромных блоков ОЗУ одновременно, например, DMA, а не в виде одной инструкции, плюс кэш ЦП ведет себя как традиционная ОЗУ, поэтому архитектуре пришлось бы абстрагировать ее как за мое первоначальное объяснение
EDIT2: В комментарии @PeterCordes мое первоначальное понимание было не совсем правильным; На самом деле x86 имеет несколько команд памяти для памяти. Настоящая причина, по которой они недоступны для большинства инструкций (например, movl и movw), заключается в том, чтобы свести сложность кодирования команд к минимуму, но они могли бы реализовать их. Однако основная идея в моем первоначальном ответе, что есть временное место хранения вне RAM в виде защелки или регистра, верна, но идея о том, что это причина, почему эти инструкции не существуют, не является. Даже старые чипы 1970-х годов, такие как 6502 и 8086, имеют инструкции памяти для памяти, и вы можете легко выполнять такие операции, как INC, непосредственно в месте расположения RAM. Это было выполнено путем фиксации выборки памяти непосредственно в ALU и обратно в память, не проходя через регистр, используемый набором команд.
Ответ 2
Насколько я знаю, в качестве общего правила в этой архитектуре допускается только один доступ к памяти для каждой инструкции. Это связано с тем, что обращение с двумя обращениями к памяти на одну инструкцию затруднит выполнение выполнения процессора.
Ответ 3
ia32 - x86, а x86 - эволюция от intel 8086 (iAPX 86). Это был небольшой и дешевый чип на основе 8-битных наборов команд и не имел "mov" с двумя явными операндами памяти.
Автор Wikipedia дает такое объяснение о кодировке команд 8086:
Благодаря компактному кодированию, основанному на использовании 8-разрядных процессоров, большинство инструкций являются одноадресными или двухадресными, что означает, что результат сохраняется в одном из операндов. Максимум один из операндов может быть в памяти, но этот операнд памяти также может быть местом назначения, в то время как другой операнд, источник, может быть либо зарегистрированным, либо немедленным. В качестве источника и места назначения часто можно использовать единую ячейку памяти, которая, помимо прочего, дополнительно способствовала плотности кода, сопоставимой с (и часто лучше) большинством восьмибитовых машин в то время.
Были некоторые CISC с инструкциями памяти-памяти (одна инструкция для работы с двумя операндами памяти). Лекция https://www.cis.upenn.edu/~milom/cis501-Fall05/lectures/02_isa.pdf говорит, что VAX может кодировать инструкции памяти:
DEC VAX (виртуальный адрес eXtension для PDP-11): 1977
- • Инструкции переменной длины: 1-321 байт!!!
- • 14 GPRs + PC + указатель стека + коды условий
- • Размеры данных: 8, 16, 32, 64, 128 бит, десятичная строка, строка
- • Инструкции памяти-памяти для всех размеров данных
- • Специальные insns: crc, insque, polyf и cast of hundred.
Это источник memcpy OpenBSD для VAX (руководство по инструкции http://h20565.www2.hpe.com/hpsc/doc/public/display?docId=emr_na-c04623178):
movq 8(ap),r1 /* r1 = src, r2 = length */
movl 4(ap),r3 /* r3 = dst */
...
1: /* move forward */
cmpl r2,r0
bgtru 3f /* stupid movc3 limitation */
movc3 r2,(r1),(r3) /* move it all */
В инструкции "movc3" имеются два операнда памяти, адреса которых хранятся в регистрах.
x86 имеет несколько команд "string", которые будут выполнять операции с памятью (* s, особенно movs - http://x86.renejeschke.de/html/file_module_x86_id_203.html), но это команда будет использовать предопределенные регистры SI и DI в качестве адресов (неявные операнды), а два операнда памяти по-прежнему не могут быть закодированы в x86.
Ответ 4
ОЗУ поддерживает ввод и вывод, но не копирование. Поэтому перемещение между памятью и памятью будет фактически перемещаться между памятью и процессором. Теоретически было бы возможно реализовать такую инструкцию, но, вероятно, это было не потому, что это было бы не очень практично.
Вот некоторые из вещей, которые необходимо учитывать для реализации такой инструкции:
-
Какое временное хранилище мы используем? Регистр?
-
Если мы используем регистр, который мы захватим?
Не предоставление такой инструкции оставляет вышеперечисленные вопросы до программиста.