регистры ассемблера - PullRequest
       1

регистры ассемблера

0 голосов
/ 03 января 2012

Я изучал программирование на ассемблере и столкнулся с некоторыми проблемами в реестрах.Например, я сталкивался с этим:

mov ax, 3000
mov ds, ax
mov si, 200
mov ax, [si]
add si, 2
add ax, [si]
add si, 2
mov [si], ax
mov ax, 4c00
int 21

этот код составляет сумму 2 сегментов памяти из 3000: 200 и 3000: 202 и помещает результат в 3000: 202, и я не понимаю связи междуDS и Си, потому что я не могу объяснить, почему мы делаем MOV DS, топор?и я вообще не понимаю связи между регистрами ... я знаю, что они обозначают, но ... я не знаю, какая помощь будет очень полезна, спасибо

Ответы [ 3 ]

3 голосов
/ 10 января 2012

DS - регистр сегмента данных - как и все регистры сегментов, его значение, умноженное на 16, представляет собой базовый адрес фрагмента памяти 64 КБ.

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

Итак, mov ax, [si] эквивалентно mov ax, [ds:si], которое (с вашими значениями регистра) представляет mov ax, [3000:200]. Внутри процессор вычислит абсолютный адрес памяти (3000 * 16) +200 и скопирует данные из этой ячейки памяти в ax. Аналогичная процедура используется для доступа к памяти при добавлении и сохранении результата.

Причина, по которой вы не можете это сделать mov ds, 3000, заключается в том, что Intel решила не поддерживать перемещение постоянных значений в сегментные регистры - для этого нет кодируемой инструкции. вместо этого вы должны передать значение через другой регистр (в вашем коде используется ax).

Ваше (оригинальное) описание не совсем верно - код добавляет значения в [3000: 200] и [3000: 202], но результат будет сохранен в [3000: 204] (не [3000: 202]).

Не забывайте: значения, хранящиеся в сегментных регистрах, таких как DS (и CS, ES, FS и GS), не указывают базовый адрес напрямую - их всегда нужно умножить на 16, чтобы получить реальный базовый адрес.

1 голос
/ 03 января 2012

Ds - регистр сегмента данных.Адрес, как вы упомянули, составлен из объединения регистра DS и регистра Si.В старые 8088/86 дней, и, возможно, все еще вы вычислили свой адрес (ds << 4) + si в этом случае.MOV to AX, то ds, потому что, возможно, есть ограничение того, что вы можете / не можете выполнить немедленно.может быть, вы не можете сделать mov ds, 3000, в любом случае ax используется как промежуточный регистр для этого, никакого соединения вообще нет, просто способ получить 3000 в регистр ds. </p>

Так что, если ds = 3000 иsi = 200, то адрес, я полагаю, (3000 << 4) +200.</p>

Подразумевается связь между ds и si.Если обратиться к справочному руководству для программистов Intel, сегмент DS используется по умолчанию при использовании SI или DI.CS: ES: SS являются альтернативами для SI (но не для DI), вам потребуется указать альтернативный сегмент в инструкции / сборке, чтобы использовать один из других сегментов.То, как вы указываете этот альтернативный сегмент, зависит от синтаксиса, который ожидает ассемблер.

0 голосов
/ 04 января 2012

Короче говоря,

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

mov ds, ax

Что касается DS и SI, у вас есть инструкция, предполагающая, что DS: SI работает должным образом, но здесь это не так. DS - ваш сегмент данных по умолчанию, поэтому он просто предполагает DS:offset; SI - это ваше смещение в вашем случае. Вы можете изменить SI на любой другой 16-битный регистр, скажем, CX , чтобы он работал аналогичным образом. Сделайте тест и ответьте мне: P

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...