Основная причина заключается в том, что большинство наборов команд допускают один операнд регистра и один операнд памяти, и соблюдение этого формата облегчает разработку декодера команд. Это также облегчает работу исполнительного механизма внутри ЦП, потому что инструкция может, как правило, выдавать операцию памяти только одной ячейке памяти, и не более одного блока чтения или записи.
Для непосредственного выполнения инструкции «память в память» необходимо указать две ячейки памяти. Это неудобно, учитывая формат команды регистр / память. Учитывая производительность машин, есть мало оснований для изменения формата инструкции только для этого.
Хак, используемый более современными ЦП, заключается в предоставлении некоторого типа инструкции перемещения блока, в которой местоположения источника и назначения расположены в регистрах (для X86 это ESI и EDI соответственно). Тогда инструкция может просто назначить два регистра (или в случае x86, инструкции, которые просто знают , который регистрирует). Это решает проблему декодирования .
Инструкция выполнение проблема немного сложнее, но у людей много транзисторов. Организовать косвенное чтение из одного регистра, а также косвенное запись через другой, и приращение и того, и другого неудобно в кремнии, но это просто жует некоторые транзисторы.
Теперь у вас может быть инструкция, которая перемещается из памяти в память, как вы и просили.
На одном из других постеров, отмеченных для X86, есть инструкции (MOVB, MOVW, MOVS, ...), которые делают именно это, один байт памяти / слово / ... за раз.
Перемещение блока памяти было бы идеальным, потому что процессор может генерировать высокоскоростные чтения и записи. X86 делает это с префиксом REP (repeat) для MOV-, чтобы переместить больший блок.
Но если это может сделать один экземпляр, у вас есть проблема в том, что выполнение может занять много времени (как долго перемещать 1 Гб? -> миллионы тактов!), И это разрушает частоту ответа прерывания CPU.
x86 решает эту проблему, позволяя прерывать REP MOV-, при этом ПК возвращается к началу инструкции. Путем надлежащего обновления регистров во время перемещения вы можете прерывать и перезапускать команду REP MOV, имеющую как быстрое перемещение блока, так и высокую скорость отклика на прерывание. Больше транзисторов в трубу.
Ребята из RISC выяснили, что вся эта сложность для инструкции перемещения блока в основном не стоит того Вы можете закодировать тупой цикл (даже x86):
copy: MOV EAX,[ESI]
ADD ESI,4
MOV [EDI],EAX
ADD EDI,4
DEC ECX
JNE copy
, который делает то же самое, что и REP MOV-. В значительной степени современные процессоры (x86 и другие) выполняют это так быстро (суперскалярный и т. Д.), Что шина используется так же, как и пользовательская инструкция перемещения, но теперь вам не нужны все эти потерянные транзисторы (или соответствующее тепло).