Les инструкция? - PullRequest
       21

Les инструкция?

6 голосов
/ 08 сентября 2011

Какова цель les инструкции по сборке?

Зачем нам загружать es сегмент и регистр? Книга приводит следующий пример:

les    bx, p           ; Load p into ES:BX
mov    es:[bx], al     ; Store away AL

Зачем нам загружать es и bx в этом случае?

Кроме того, почему мы используем es:[bx]? Если p указывает на 100h в памяти, не являются ли es и bx 100h = 200h (bx+es)?

Ответы [ 3 ]

9 голосов
/ 08 сентября 2011

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

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

Некоторые машины (особенно Intel 286, которая, кажется, является тем, что вы программируете), имели только 16-битные регистры, но могли адресовать 1 МБ памяти. В этом случае регистру не хватает битов: вам нужно 20 бит, но регистры только 16 бит.

Решение состоит в том, чтобы иметь второй регистр, который содержит пропущенные биты. Простая схема состояла бы в том, чтобы потребовать 2 регистра, один из которых имел младшие 16 бит, один из которых имел старшие 16 бит, чтобы получить 32-битный адрес. Тогда инструкция, которая ссылается на два регистра, имеет смысл: вам нужно оба, чтобы получить полный адрес памяти.

Intel выбрала более сложную схему: индексный регистр (в нашем случае bx) содержит младшие 16 бит, а другой регистр (называемый ES) содержит 16 битов, которые сдвинуты влево на 4 бита и добавлены в индексный регистр, чтобы получить результирующий адрес. ES называется «сегментным» регистром, но это не имеет смысла, если вы не прочитаете о операционной системе Multics около 1968 года.

[Сегменты и сегментные регистры действительно являются интересной идеей, когда полностью реализован способ Multics. Если вы не знаете, что это такое, и у вас есть любой интерес к компьютерам и / или информационным архитекторам, найдите книгу Elliot Organick по Multics и прочитайте ее от корки до корки. Вы будете потрясены тем, что мы имели в конце 60-х годов, и, кажется, потеряли за 50 лет «прогресса».]

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

Для Intel 286 вам просто нужно загрузить регистр сегмента и регистр индекса, чтобы получить полный адрес. Каждое машинное обращение должно ссылаться на один индексный регистр и один сегментный регистр, чтобы сформировать полный адрес. Для Intel 286 существует 4 таких сегмента реигстера: DS, SS, ES и CS. Каждый тип инструкции явно обозначает индексный регистр и неявно выбирает один из 4 сегментных регистров, если вы не предоставите явное переопределение, в котором указано, какой из них использовать. Инструкции JMP используют CS, если вы не говорите иначе. В инструкциях MOV используется DS, если не указано иное. В инструкциях PUSH используется SS, если не указано иное (в этом случае лучше не использовать). ES - «лишний» сегмент; Вы можете использовать его только путем явного указания в инструкции (кроме инструкции перемещения блока [MOVB}, которая неявно использует как DS, так и ES).

Надеюсь, это поможет.

Лучше всего работать с более современным микропроцессором, где глупость сегментного регистра не является проблемой.

5 голосов
/ 08 сентября 2011

Сегментные регистры 8086 cs, ds, es и ss представляют собой оригинальный механизм, с помощью которого 16-разрядные регистры могут адресовать более 64 КБ памяти. В 8086/8088 нужно было генерировать 20-битные адреса (1024 K). Последующие версии процессоров x86 добавили новые схемы для еще большего адреса, но основной причиной является генерация 20+ битов адреса из пары 16-битных значений.

В так называемом «реальном режиме» (собственный для 8086/8088/80186/80286) адрес вычисляется путем умножения содержимого регистра сегмента на 16 (или, что эквивалентно, смещения влево на четыре позиции) и добавления смещение.

В защищенном режиме (доступен с 80386 и более поздними версиями) регистр сегмента выбирает «дескриптор», который содержит базовый физический адрес. Например, операнд es:[bx] добавляет bx к этому физическому адресу для генерации адреса операнда.

3 голосов
/ 08 сентября 2011

p указывает на 32-битный указатель FAR с сегментом и частью смещения (в отличие от указателя NEAR, который является только частью смещения).LES загрузит сегмент: смещение в ES:BX.

В противном случае вам придется использовать три инструкции.Один для загрузки BX и два для загрузки ES (регистры сегментов не могут быть загружены непосредственно из памяти, но должны быть загружены в регистр общего назначения, а затем в регистр сегментов).

О,да, у Wallyk была хорошая мысль упомянуть защищенный режим (хотя это и не относится к вашему вопросу).Здесь ES будет интерпретироваться как селектор, а не фактический сегмент.

Сегмент (адрес) в этом контексте является частью физического адреса:
Сдвиг сегмента на 4 бита длявлево (т.е. умножьте его на 2 ^ 4 = 16) и добавьте смещение, чтобы получить физический адрес из сегмента: смещение.

Напротив, селектор - это указатель на запись в так называемой таблице дескрипторов(т.е. селектор указывает на дескриптор) и используется в защищенном режиме.Таблица дескрипторов (например, GDT ) может содержать записи информации о порциях памяти, в том числе информацию об адресе физической памяти, размере порции, правах доступа и т. Д. (Есть также несколько других применений).

...