Почему IA32 не позволяет память переместить в память?

В архитектуре Intel IA32 такие инструкции, как movl, movw, не разрешают операнды, которые являются обеими ячейками памяти. Например, инструкция movl (% eax), (% edx) не разрешена. Почему?


person Strin    schedule 14.08.2012    source источник
comment
Байт ModR / M не может его закодировать. Но тогда, конечно, вы можете превратить это в вопрос, почему они сделали это так, ну ... между тем, перемещение строки (movsb, movsw, movsd, movsq) имеет два аргумента памяти, но они неявны.   -  person harold    schedule 14.08.2012
comment
Это 1976 год, и вы можете поместить 20 000 транзисторов на микросхему, чтобы реализовать 16-битный процессор. Это требует серьезного срезания углов, и очень неортогональный дизайн был частью результата. И нет места для поиска памяти, необходимой для буферизации значения между циклами шины.   -  person Hans Passant    schedule 15.08.2012
comment
Я думаю, что лучшее объяснение состоит в том, что для декодирования insns с двумя режимами полной адресации (base + index + disp16) потребовалось бы два AGU (блоки генерации адресов), и это сильно усложнило бы формат двоичного машинного кода. (какое переопределение сегмента применяется к какому операнду? Как разрешить кодирование двух адресов памяти без увеличения размера кода для общего случая, когда один или оба операнда являются регистрами?)   -  person Peter Cordes    schedule 21.04.2016
comment
@PeterCordes В оригинальном 8086 не было даже одного блока генерации адресов, так что причина не в этом. Он обращался к вычислениям с помощью ALU.   -  person Ross Ridge    schedule 17.07.2016


Ответы (4)


Ответ предполагает более полное понимание RAM. Проще говоря, ОЗУ может находиться только в двух состояниях: в режиме чтения или записи. Если вы хотите скопировать один байт из ОЗУ в другое место, вы должны иметь область временного хранения вне ОЗУ, когда вы переключаетесь с чтения на запись.

Конечно, архитектура может иметь такую ​​инструкцию RAM to RAM, но это будет инструкция высокого уровня, которая в микрокоде будет транслироваться в копирование данных из RAM в регистр, а затем обратно в RAM. В качестве альтернативы, можно было бы расширить контроллер RAM, чтобы иметь такой временный регистр только для этого копирования данных, но это не принесет большого преимущества из-за дополнительной сложности взаимодействия CPU / оборудования.

РЕДАКТИРОВАТЬ: Стоит отметить, что последние достижения, такие как куб гибридной памяти и память с высокой пропускной способностью, представляют собой архитектуры, в которых топология ОЗУ стала больше похожа на PCI-e, и теперь возможна прямая передача ОЗУ в ОЗУ, но это связано с логикой поддержки технологий, а не с самой оперативной памятью. В архитектуре ЦП это будет в форме огромных блоков ОЗУ за раз, например, DMA, а не в виде одной инструкции, плюс кеш ЦП ведет себя как традиционная ОЗУ, поэтому архитектура должна абстрагировать его как согласно моему первоначальному объяснению

РЕДАКТИРОВАТЬ2: Согласно комментарию @PeterCordes, мое первоначальное понимание было не совсем правильным; На самом деле x86 имеет несколько инструкций из памяти в память. Настоящая причина, по которой они недоступны для большинства инструкций (таких как movl и movw), состоит в том, чтобы снизить сложность кодирования инструкций, но они могли бы их реализовать. Однако основная идея в моем первоначальном ответе о том, что существует временное хранилище вне ОЗУ в виде защелки или регистра, верна, но идея о том, что это причина, по которой эти инструкции не существуют, - нет. Даже более старые микросхемы 1970-х годов, такие как 6502 и 8086, имеют инструкции из памяти в память, и вы можете легко выполнять такие операции, как INC, непосредственно в области ОЗУ. Это было достигнуто путем фиксации выборки из памяти непосредственно в ALU и повторного возврата в память без прохождения через регистр, используемый набором команд.

person Dougvj    schedule 14.08.2012
comment
В x86 это ограничение insn-кодирования, а также сохранение низкой сложности декодирования. Есть инструкция копирования из памяти в память (movs), но она использует два неявных операнда. Также есть push/pop [mem] для чтения с действующего адреса, закодированного в insn, и записи в [rsp]. (или наоборот, push vs. pop). У оригинального 8086 были эти insns, и у него был довольно маленький бюджет транзистора (но, очевидно, достаточно большой, чтобы зафиксировать 16 бит между чтением и записью). В современных процессорах rep movs действительно эффективен для блочных копий больших выровненных буферов. - person Peter Cordes; 21.04.2016
comment
Кроме того, все инструкции назначения памяти, такие как inc byte [mem], выполняют чтение-изменение-запись в память. Это по тому же адресу, но это все еще две отдельные команды. Это неплохая догадка, но она практически не связана с правильным ответом. - person Peter Cordes; 17.07.2016
comment
@PeterCordes Спасибо за ваш вклад. Я узнал немного больше с тех пор, как написал этот ответ и понял, что был не совсем прав. Я добавил правку, отмечая это в ответе. - person Dougvj; 06.08.2017
comment
IA32 использует тот же набор инструкций, что и 8086, только с некоторыми 32-битными расширениями. inc dword [eax] существует в IA-32. (Или синтаксис AT&T, incl (%eax). Похоже, ваш последний абзац утверждает, что 6502 и 8086 имеют это, а IA-32 нет. - person Peter Cordes; 21.03.2018
comment
@PeterCordes Это не было моим намерением, но я не знаю, как это сделать яснее. Идите вперед и предложите отредактировать. - person Dougvj; 21.03.2018
comment
О, при втором чтении я не думаю, что это подразумевает, nvm. Этот ответ все еще нуждается в переписывании, чтобы начать с правильных причин, а не ошибаться, а затем закапывать правильный ответ в обновлении EDIT. Ваш ответ не должен быть журналом изменений, это должен быть лучший ответ, который вы можете сделать. - person Peter Cordes; 21.03.2018
comment
@PeterCordes Имеет смысл. Я не был хорошо знаком с этикетом, связанным с такими тяжелыми переписываниями, поэтому избегал этого. Когда-нибудь, когда у меня будет больше времени и интереса, я сделаю это. Вы должны написать свой собственный ответ, конечно, это будет лучше. - person Dougvj; 21.03.2018
comment
@Dougvj: оказывается, я действительно уже написал ответ на movl from память в память, объясняя, почему машинное кодирование и ISA-дизайн (и производительность на современных процессорах) не имеют инструкций mem, mem. Этот вопрос - точный обман; Я мог бы и, возможно, должен был бы репостить это здесь. - person Peter Cordes; 30.03.2018

ia32 - это x86, а x86 - это эволюция Intel 8086 (iAPX 86). Это была небольшая и дешевая микросхема, основанная на 8-битных наборах инструкций и не имевшая "mov" с двумя явными операндами памяти.

Автор Википедии дает такое объяснение кодировки инструкций 8086:

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

Было несколько CISC с инструкциями память-память (одна инструкция для работы с двумя операндами памяти). Лекция https://www.cis.upenn.edu/~milom/cis501-Fall05/lectures/02_isa.pdf говорит, что VAX может кодировать инструкции память-память:

DEC VAX (расширение виртуального адреса для PDP-11): 1977 г.

  • • Инструкции переменной длины: 1-321 байт !!!
  • • 14 георадаров + ПК + указатель стека + коды состояния
  • • Размеры данных: 8, 16, 32, 64, 128 бит, десятичные, строковые.
  • Инструкции память-память для всех размеров данных.
  • • Специальные insns: crc, insque, polyf и cast of 100

Это исходный код OpenBSD memcpy для VAX (руководство по набору инструкций http://h20565.www2.hpe.com/hpsc/doc/public/display?docId=emr_na-c04623178):

https://es.osdn.jp/projects/openbsd-octeon/scm/git/openbsd-octeon/blobs/master/src/sys/lib/libkern/arch/vax/memcpy.S

         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 имеет несколько «строковых» инструкций, которые будут выполнять операции память-память (* s, особенно movs - http://x86.renejeschke.de/html/file_module_x86_id_203.html), но эта инструкция будет использовать предопределенные регистры SI и DI в качестве адресов (неявные операнды), а два операнда памяти по-прежнему не могут быть закодированы в x86.

person osgx    schedule 17.07.2016
comment
Есть идеи, как машинному коду VAX удается оставаться компактным, когда у инструкции есть только один или нулевой операнд памяти? Это проблема для x86, где исходный 8086 имел довольно простое декодирование инструкций. (Это и, возможно, потребуется два AGU или два использования одного AGU). 8086 пришлось бы делать что-то более сложное, чем байт mod / rm, возможно, с кодировкой переменной длины, такой как байт SIB 386. VAX, по-видимому, удается поддерживать режимы адресации с масштабируемым индексом (с или без увеличения / уменьшения)! - person Peter Cordes; 17.07.2016
comment
NVM, нашел: 2.2. Режимы адресации VAX-11 поддерживает шестнадцать режимов адресации. Каждый операнд представлен в памяти спецификатором операнда, который состоит из байта режима, за которым следуют от нуля до пяти дополнительных байтов информации. Байт режима разбит на два поля: четырехбитовый указатель режима и четырехбитовый указатель регистра. Из (html-кеша Google) users.cs.jmu.edu/abzugcx/Public/Student-Produced-Term-Projects/ < / а>. - person Peter Cordes; 17.07.2016
comment
Довольно громоздко по сравнению с 8086, особенно. так как я слышал, что исходное оборудование 8086 по сути всегда было узким местом при извлечении кода. - person Peter Cordes; 17.07.2016
comment
Питер, что ты думаешь о своем собственном правильном ответе? - person osgx; 17.07.2016
comment
Пишу ответ прямо сейчас. IIRC, этот вопрос был ранее закрыт как основанный на мнении или что-то в этом роде, иначе я бы уже опубликовал его. Просматривая свои предыдущие комментарии к этому посту, я начинал понимать, что сейчас мне нужно просто ответить на него сам. - person Peter Cordes; 17.07.2016
comment
Обновление, я уже написал ответ по этому поводу почти за год до моего последнего комментария: Почему нельзя перемещать из памяти в память?. Наконец-то я заметил этот старый комментарий и другой мой ответ одновременно. - person Peter Cordes; 18.10.2018

Насколько мне известно, как правило, в этой архитектуре разрешен только один доступ к памяти для каждой инструкции. Это связано с тем, что обработка двух обращений к памяти на инструкцию усложнила бы конвейер выполнения процессора.

person whooot    schedule 14.08.2012
comment
Есть такое правило, но это про микропроцессоры Intel. - person harold; 14.08.2012
comment
SCAS *, MOVS *, PUSH / POP mem, PUSHA / POPA и некоторые другие инструкции имеют доступ к нескольким словам памяти. Но не все их операнды в памяти закодированы с использованием байта Mod R / M, который может относиться не более чем к одному операнду в памяти. - person Alexey Frunze; 14.08.2012

ОЗУ поддерживает ввод и вывод, но не копирование. Следовательно, перемещение из памяти в память на самом деле будет перемещением из памяти в процессор в память. Теоретически такую ​​инструкцию можно было бы реализовать, но, вероятно, этого не произошло, потому что это было бы не очень практично.

Вот некоторые из вещей, которые необходимо учитывать при реализации такой инструкции:

  • Какое временное хранилище мы используем? Регистр?

  • Если мы используем реестр, какой из них мы взламываем?

Отсутствие такой инструкции оставляет вышеуказанные вопросы на усмотрение программиста.

person Kendall Frey    schedule 14.08.2012
comment
Но они предоставили его, см. movsb и его семью. И, конечно же, регистр не обязательно должен быть архитектурным. - person harold; 14.08.2012
comment
В добавление к Гарольду, @ Кендалл: - Как вы думаете, в каком регистре происходит захват команд ?? и почему что-то в этом роде нельзя здесь использовать ??? - person perilbrain; 14.08.2012