08F1 * 10 = 08F10 (Линейный адрес начала сегмента) К адресу

advertisement
Глава 2 Структура процессоров семейства IA32
96
Пример. Предположим, что адрес некоторой переменной, заданный в шестнадцате*
ричном виде и в форме “сегмент*смещение”, равен 08F1:0100. При вычислении ли*
нейного адреса ЦПУ должен умножить сегментную часть адреса на 10h и прибавить к
полученному результату смещение, как показано ниже:
08F1 * 10 = 08F10
(Линейный адрес начала сегмента)
К адресу начала сегмента:
0 8 F 1 0
Прибавляем смещение:
Получаем линейный адрес:
0 1 0 0
0 9 0 1 0
В типичной программе, написанной для процессоров семейства IA*32, как правило,
есть три сегмента: кода, данных и стека. При запуске программы их базовые сегментные
адреса загружаются в регистры CS, DS и SS, соответственно. В трех оставшихся регистрах
ES, FS и GS программа может хранить указатели на дополнительные сегменты.
2.3.2. Защищенный режим
Теперь пришло время поговорить о самом развитом режиме работы процессора, в ко*
тором можно реализовать все его возможности, задуманные разработчиками. При работе
в защищенном режиме каждой программе может быть выделен блок памяти размером до
4 Гбайт, адреса которого в шестнадцатеричном представлении могут меняться от
00000000 до FFFFFFFF. При этом говорят, что программе выделяется линейное адресное
пространство (flat address space), которое разработчики компилятора Microsoft Assembler
назвали линейной моделью памяти (flat memory model). С точки зрения программиста, ли*
нейная модель наиболее проста в использовании, поскольку для хранения адреса любой
переменной или команды достаточно одного 32*разрядного целого числа. Эта иллюзия
простоты во многом достигается за счет того, что часть работы программиста по реализации
встроенных возможностей процессора выполняет операционная система. В защищенном
режиме в сегментных регистрах (CS, DS, SS, ES, FS, GS) хранятся не 16*разрядные базо*
вые адреса сегментов, а указатели на дескрипторы сегмента (segment descriptor), располо*
женные в одной из системных таблиц дескрипторов (descriptor table). По информации, на*
ходящейся в дескрипторе, операционная система определяет линейные адреса сегментов
программы.
В типичной программе, написанной для защищенного режима, как правило, есть три
сегмента: кода, данных и стека, информация о которых хранится в трех перечисленных
ниже сегментных регистрах.
•
В регистре CS хранится указатель на дескриптор сегмента кода программы.
•
В регистре DS хранится указатель на дескриптор сегмента данных программы.
•
В регистре SS хранится указатель на дескриптор сегмента стека программы.
2.3.2.1. Линейно!сегментная модель памяти
В этой модели (flat segmentation model) дескрипторы всех сегментов указывают на один
и тот же сегмент памяти, который соответствует всему 32*разрядному физическому адрес*
ному пространству компьютера. При этом для каждой программы операционная система
3.2. Пример: сложение трех целых чисел
•
129
Использовать прописные буквы для написания только директив и операторов
языка ассемблера, а все остальные конструкции писать строчными буквами.
Именно этот подход использован при оформлении примеров к этой книге за од+
ним исключением: директивы .code и .data пишутся прописными буквами.
3.2.3.1. Альтернативный вариант программы AddSub
После анализа программы AddSub вы наверняка захотите узнать, что же “спрятано” в
файле Irvine32.inc. Чтобы облегчить чтение кода нашей программы, мы “упрятали”
в этот файл некоторые технические детали, которые будут рассмотрены в последующих
главах этой книги. Понятно, что преподаватель может попросить вас написать программу
без использования включаемых файлов, поэтому ниже приведена версия программы
AddSub, в которой ничего не скрыто:
TITLE Сложение и вычитание (AddSub.asm)
; В этой программе складываются и вычитаются 32-разрядные целые числа.
.386
.MODEL flat,stdcall
.STACK 4096
ExitProcess PROTO, dwExitCode:DWORD
DumpRegs PROTO
.code
main PROC
mov eax,10000h
add eax,40000h
sub eax,20000h
call DumpRegs
; EAX = 10000h
; EAX = 50000h
; EAX = 30000h
INVOKE ExitProcess,0
main ENDP
END main
В этой версии программы есть несколько отличий от той, что мы рассматривали вы+
ше. Как и прежде, проведем построчный анализ программы и подробно опишем каждую
новую строчку.
.386
Директива .386 определяет тип процессора, для которого создается программа
(в данном случае Intel386 и более старшие модели).
.MODEL flat,stdcall
Эта директива .MODEL указывает компилятору, что нужно генерировать код для за+
щищенного режима работы процессора, а параметр STDCALL позволяет вызывать в про+
грамме функции системы MS Windows. (Точнее, она определяет порядок передачи пара+
метров процедуре, но об это чуть позже.)
Download