Почему инструкция mov использует ax вместо двух сегментных регистров напрямую?

Я вижу такой код:

mov ax, cs
mov ds, ax
mov es, ax

Почему я не могу просто сжать это до:

mov ds, cs
mov es, cs

Является ли первый способ быстрее, поскольку он использует регистр аккумулятора? Но это не кажется интуитивным, поскольку cs и ds являются сегментными регистрами. Или есть какие-то ограничения, о которых я не знаю?

Кстати, я использую nasm.


person samoz    schedule 29.05.2009    source источник


Ответы (4)


Вы не можете перемещать сегментный регистр в сегментный регистр — для этого нет инструкций.

person Dave    schedule 29.05.2009
comment
Когда я впервые прочитал ваш ответ, я не поверил вам, но в документации NASM, конечно же, нет инструкции mov reg_dseg, reg_cseg. - person samoz; 30.05.2009
comment
Это не причина, это следствие. - person ; 30.05.2009
comment
Какой? Я не понимаю, что ты имеешь в виду, Нил. - person samoz; 30.05.2009
comment
Спросите себя, ПОЧЕМУ x86 не имеет этих конкретных инструкций. - person ; 30.05.2009
comment
@Neil - На самом деле это является ответом на вопрос «Почему авторы книг не используют mov ds, cs?» и даже более конкретно его вопрос, есть ли какое-то ограничение, о котором я не знаю? Однако следующим закономерным вопросом будет, почему бы и нет? так что ваш ответ полезен там. - person dss539; 30.05.2009

В процессоре достаточно места для микрокода для всех его инструкций. Таким образом, одна общая инструкция часто предпочтительнее нескольких специальных для редко используемых операций по изменению сегментных регистров. Кроме того, для некоторых процессоров количество инструкций абсолютно ограничено архитектурой — например, исходный процессор 8080 был ограничен 256 инструкциями, поскольку все они должны были иметь код операции, закодированный одним байтом.

person Community    schedule 29.05.2009
comment
Кодовое пространство в машинном коде также является проблемой для 8086. Предположительно, они хотели оставить место для будущего расширения. Помимо пространства для микрокода, существует сложность аппаратного обеспечения декодера для поддержки декодирования большего количества различных кодов операций. (Разве само декодирование 8086 не выполнялось микрокодом? IDK). Но да, тратить код операции на редко используемую инструкцию, которая (когда она используется) сохраняет только 1 2-байтовую инструкцию по сравнению с альтернативой, того не стоит. - person Peter Cordes; 21.03.2020

Посмотрите Руководство Intel, том 2. Справочник по набору инструкций — 325383-056US, сентябрь 2015 г. Столбец «MOV Move» «Инструкция».

Единственное 16-битное перемещение в регистры закодировано в:

mov r/m16, Sreg

И «3.1.1.3 Столбец инструкций в сводной таблице кодов операций» объясняет:

  • r/m16 — Регистр слова общего назначения или операнд памяти, используемый для инструкций, атрибут размера операнда которых равен 16 битам. Слово регистры общего назначения: AX, CX, DX, BX, SP, BP, SI, DI.
  • Sreg — регистр сегмента.

Таким образом, mov ds, cs не кодируется, так как нет версии mov Sreg, Sreg.

person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 31.10.2015

На самом деле это не язык ассемблера, а базовый машинный язык, который предотвращает эти операции.

Хотя ассемблер состоит из легко читаемых слов или мнемоник, на самом деле они представляют собой единицы и нули машинного кода. В процессорах x86 каждая инструкция обычно состоит из последовательности байтов, где отдельные байты или даже биты внутри байтов имеют значение. Одни биты представляют инструкцию, другие — режим адресации. В режимах адресации регистров, таких как ваши примеры, некоторые биты представляют, какие конкретные регистры должны использоваться в качестве источника и назначения инструкции mov.

Теперь семейство процессоров x86 восходит к 1970-м годам, когда архитектура ЦП была проще. В те дни концепция аккумулятора имела ключевое значение — ax это 16 -битный аккумулятор x86. Все расчеты строились или «накапливались» в этом регистре, так что он был доступен для всех инструкций. Другие регистры общего назначения имели более ограниченный диапазон использования.

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

В более современных процессорах, таких как Motorola 680x0, регистры более общего назначения имеют больше возможностей, чем ранее были прерогативой аккумулятора. В ЦП RISC все регистры такие же гибкие, как аккумуляторы. Я слышал, что в 64-битном режиме текущий набор инструкций x86/amd64 теперь гораздо менее ограничен.

person hippietrail    schedule 09.05.2011
comment
Только в x86_64 эти регистры можно будет использовать таким образом. Начиная с 32-битной архитектуры x86, большинство регистров могут действовать более или менее как регистры общего назначения. - person phuclv; 17.03.2014
comment
Похоже, я не знал, что вопрос был о сегментных регистрах, а также об аккумуляторе. Я никогда не занимался сборкой x86 из-за того, что память работала ужасно, а затем с сегментными регистрами и прочим. Я считаю, что теперь гораздо приятнее работать, когда есть хорошая плоская модель памяти. - person hippietrail; 17.03.2014
comment
Хоть и х86 сборку особо не езжу. Но на x86 тоже есть сегментные инструкции. Адресное пространство x86 не плоское - person phuclv; 17.03.2014
comment
Это сложнее, чем это. Существуют различные режимы, которые добавлялись на протяжении поколений, и различные операционные системы не всегда использовали самый мощный доступный режим в то время. В процессорах x86 осталось множество вещей для обратной совместимости. В наши дни в современных ОС вам не нужно беспокоиться о сегментах. Вот что я имею в виду под плоской моделью памяти. Я не знаю, насколько сегментные регистры используются в наши дни, нужны ли они, или это просто регистры общего назначения, сохранившие свои старые имена... - person hippietrail; 17.03.2014
comment
Ваш первый абзац цельный, но остальные схематичны. mov r/m, Sreg и mov Sreg, r/m могут использовать любой целочисленный регистр GP или режим адресации в качестве операнда, отличного от Sreg. Они не ограничиваются AX. В общем, даже 8086 может делать что-то вроде add bx, cx с тем же кодом операции, что и для add ax, cx, только с другим назначением в байте ModRM, кодирующем операнды. x86 не является аккумуляторной машиной. AX был особенным для некоторых операций на 8086, но не для большинства основных операций с ALU. (В отличие от 8080, где A был гораздо более особенным). 386 сделал AX менее особенным - person Peter Cordes; 21.03.2020