Ассемблер mov проблема

У меня есть следующий код:

mov  ax,@data
mov  ds,ax

Почему я не могу писать просто так?

mov ds,@data

Весь источник:

   .MODEL small
   .STACK 100h
   .DATA
   HelloMessage DB 'Hello, world',13,10,'$'
   .CODE 
   .startup
   mov  ax,@data
   mov  ds,ax
   mov  ah,9
   mov  dx,OFFSET HelloMessage
   int  21h
   mov  ah,4ch
   int  21h
   END

Благодарю вас!


person Alex Pliutau    schedule 11.09.2010    source источник


Ответы (3)


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

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

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

person starblue    schedule 11.09.2010
comment
+1 Вы также можете сказать, что причина невозможности изменить ds с помощью одной из стандартных инструкций mov заключается в том, что только 3 бита зарезервированы для кодирования регистра назначения в большинстве инструкций, и что ax,bx,cx,dx,si ,di,sp,bp уже используют все доступные возможности. Но это было бы несколько упрощением. - person Pascal Cuoq; 11.09.2010
comment
Да, это конкретное дизайнерское решение сделать инструкции маленькими. - person starblue; 11.09.2010
comment
В таком случае при чем тут mov ds,ax? Я почти уверен, что это mov с ds в качестве регистра назначения ;) У вас есть веский аргумент, а я просто играю! - person Lazarus; 11.09.2010
comment
@Lazarus mov ds,... не является mov с ds в качестве целевого регистра. Это удобное обозначение для другой инструкции. См. pdos.csail.mit.edu/6.828/2004/readings. /i386/MOV.htm - person Pascal Cuoq; 11.09.2010
comment
@Pascal Cuoq: И, как я уже сказал, ваш аргумент был здравым, и я играл ... или вы дошли до своей ветки до того, как дошли до этой части предложения, или вы просто решили проигнорировать это. - person Lazarus; 11.09.2010

Регистр общего назначения как «топор» предназначен для хранения 16-битного числа, указывающего на данные (в вашем случае строка внутри ДАННЫХ)

Поэтому, если вы попытаетесь напрямую передать данные в специальный регистр (здесь ds или сегмент данных), он не будет работать правильно, поскольку он не знает, как принимать данные таким образом. Итак, мы сначала получаем это «число» или точку в ячейке памяти, где начинаются данные, и передаем эту точку в регистр ds.

person loxxy    schedule 11.09.2010

Я не эксперт, но я так понимаю, что это ограничение работает.

Регистры сегментов используются для управления тем, какой сегмент памяти используется инструкциями регистров, поэтому последнее, что вам нужно, — это загрузить регистр сегмента (в данном случае DS, который является регистром сегмента данных) из ячейки памяти. Действие модификации DS может привести к изменению считываемой области памяти в процессе обновления DS, т. е. первые биты/байты, загруженные в DS, теперь приводят к тому, что он указывает на другой сегмент до того, как оставшаяся часть будет прочитана. Безопаснее считывать значение в аккумулятор (AX) или другой регистр общего назначения, так что теперь значение находится в процессоре, когда оно загружается в сегментный регистр, поэтому нет шансов, что значение будет повреждено во время загрузки.

person Lazarus    schedule 11.09.2010
comment
Я не думаю, что это причина, поскольку DS можно легко обновить после того, как будет прочитано полное значение. - person starblue; 11.09.2010
comment
Если бы это было объяснением, не было бы такой инструкции, как mul ax, потому что ax могло бы быть повреждено при умножении. - person Pascal Cuoq; 11.09.2010
comment
@starblue, его можно легко обновить таким образом, если у процессора есть место, в которое можно прочитать значение перед загрузкой его в DS (скажем, mov ax,@Data, затем mov ds,ax), однако эффективность дизайна может заключаться в том, что загружаемое значение направляется в регистр. Я не говорю, что я определенно прав, я говорю, что это не невероятно. - person Lazarus; 11.09.2010
comment
@Pascal Cuoq: Хотя я не согласен с тем, что мое объяснение может быть неверным, я не согласен с вашим подтверждением. mul ax выполняется полностью внутри процессора, доступ к памяти через сегментный регистр не осуществляется. В конце концов, AX является аккумулятором и предназначен для выполнения собачьей работы, более чем вероятно, что любые особые случаи будут применяться к этому регистру в дополнение к любому другому. - person Lazarus; 11.09.2010
comment
@Lazarus Я собирался использовать более техническое объяснение, что современные процессоры имеют десятки версий одного и того же регистра, существующих в один и тот же момент, и что версия до инструкции и версия после инструкции не кажутся чем-то, что должно пугать разработчиков , но это все равно было бы немного неправильно, потому что набор инструкций был разработан до выполнения не по порядку. По правде говоря, ваш ответ настолько далек от фактического функционирования процессора, что его трудно опровергнуть. - person Pascal Cuoq; 11.09.2010
comment
@Pascal Cuoq: на самом деле я не пытаюсь быть сложным, я пытаюсь получить фактический ответ, который, как показывают ваши комментарии, у вас есть. Вы признаете, что набор инструкций был разработан до внеочередного выполнения, но затем заявляете, что мой ответ совершенно неверен. Я мог бы согласиться с тем, что это было просто произвольное решение, основанное на доступном размере инструкции, но, как вы указали в другом месте, MOV DS — это инструкция, отличная от MOV AX, так почему бы не разрешить расположение памяти, когда сопряжение так очень, очень распространено? - person Lazarus; 11.09.2010
comment
Я подозреваю, что мы никогда не докопаемся до истины. Я принимаю, что мой ответ является чистой спекуляцией, даже с опытом работы с аппаратными ICE, слишком далеко во времени и памяти :) - person Lazarus; 11.09.2010
comment
8086 был 16-битным с самого начала в семидесятых, поэтому он предназначен для доступа к памяти 16-битными словами en.wikipedia.org/wiki/8086#Details . 8-битный 8088 появился позже, и он должен был учитывать логическое представление о доступе к 16-битному коду в целом. - person starblue; 15.09.2010
comment
Это действительно хорошее замечание @starblue. Все еще кажется странным, что если это просто произвольное решение отказаться от инструкции, то почему именно она, когда она так часто используется. - person Lazarus; 15.09.2010