Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

как получить эффективный адрес (В NASM без использования LEA) по отношению к какому либо сегменту если есть смещение

83K
24 ноября 2013 года
Mr.Sharps
7 / / 24.11.2013
Мужики, назрел вот такой вот дилетантский вопрос в процессе изучения NASM ,но сначала начну с предыстории возникшей дилеммы.

Как мы знаем в asm адресация бывает косвенная и обычная тут всё прозрачно соответственно если у нас операнд в ячейке памяти то для того чтобы к нему обратиться например в команде mov пишем:

mov eax, [ адрес || указатель ]

или же если мы адрес закинули в регистр:

mov eax, [ebx]

Далее каждый знает что у нас есть сегментные регистры возьмём к примеру ds. Обычно к сегментным регистрам данных привязывают сегменты с зарезервированными ячейками памяти либо с конкретным значением то есть в этот регистр помещается начальный адрес нашего сегмента и чтобы в дальнейшем обратиться какой либо его части адресного пространства мы используем смещение то есть смещаемся на какое то количество ячеек по отношению к базовому адресу но самое главное что для этого нам нужно знать только смещение и селектор а реальный адрес мы в голове не держим :

ds:0x81

Итак тут то меня и смутило то что если я хочу получить этот эффективный адрес и закинуть его в регистр для дальнейших манипуляций NASM ругается на вот такую запись :

mov eax, ds:0x81

И это при том что если мы проинициализируем какую либо ячейку в памяти и присвоим ей метку а далее напишем вот так :

string db "ЛОЛ$"
mov eax,string

То он это проглотит да ещё и адрес этой метки кинет в наш регистр.
Так вот мой вопрос в том что почему инструкция mov eax, ds:0x81 не работает ведь по логике вещей должна
349
25 ноября 2013 года
Phantom-84
656 / / 27.10.2005
Но вы ведь не написали mov eax,ds:string, зачем же вы тогда пишете mov eax,ds:0x81?

Если вы хотите поместить в eax адрес 0x81, так и пишите: mov eax,0x81. А когда уже будете обращаться к памяти по этому адресу, то укажите сегмент: mov cl,[ds:eax] (кстати если в качестве базового регистра не используется ebp или esp, то сегментный регистр ds будет использоваться по умолчанию - его можно не писать). Или напрямую: mov cl,[ds:0x81].
349
25 ноября 2013 года
Phantom-84
656 / / 27.10.2005
Несколько слов по вопросу в топике... Эффективный адрес в терминологии Интел - это и есть внутрисегментное смещение. Команда LEA предназначена для того, чтобы его получать из нескольких составляющих, способных использоваться как вместе, так и по отдельности: база, индекс (*1, 2, 4 и т.п.) и смещение относительно суммы двух пред. составляющих. Причем писать просто lea eax,[es:0x81] бессмысленно - вы все равно не получите в eax отличное от 0x81 значение вне зависимости от содержимого регистра es. Проще и эффективнее написать просто mov eax,0x81.

В реальном режиме в сегментных регистрах содержатся базовые адреса сегментов без мл. 4 бит, т.е. фактически - базовые адреса, разделенные на 16. Т.е. вычисление линейного адреса нужно выполнять по формуле сегмент*16+смещение. В защищенном режиме в сегментных регистрах содержатся т.н. селекторы, значения которых вообще не дают никакого представления о базовых адресах соответствующих сегментов - за базовыми адресами сегментов нужно обращаться к таблице дескрипторов сегментов (GDT или LDT). Т.е. определение линейного адреса становится еще сложнее.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог