ЭВУ 2 семестр / Презентации ЭВУ в пдф / метода моховикова
.pdf
; Данные
arg0 |
dw 0 |
arg1 |
dw 12 |
argN |
dw 345 |
;----------------------------------------
-----------------------------
; Код
push [argN] push ...
push [arg1] push [arg0] call myproc
Рис. 30. Ис-
пользование стека при вызове
Обращение к параметрам внутри процедуры
Для обращения к параметрам внутри процедуры обычно используют ре-
гистр BP. В самом начале процедуры содержимое регистра BP сохраняется в стеке и в него копируется значение регистра SP. Это позволяет «запомнить» положение вершины стека и адресовать параметры относительно регистра
BP. При выполнении кода процедуры стек будет иметь структуру, показан-
ную на рис. 31.
;Процедура myproc:
push bp mov bp,sp
...
mov ax,[bp+4] |
;AX = |
arg0 |
|
mov bx,[bp+6] |
;BX |
= arg1 |
|
add ax,[bp+8] |
;AX |
= AX + arg2 |
|
Рис. 31. Структура стека при обращении внутри процедуры
81
Здесь ret_addr обозначает адрес возврата, помещаемый в стек командой вызова процедуры, а bp – сохраненное значение регистра BP. В нашем случае стек имеет ширину 16 бит, поэтому первый параметр будет доступен как word[bp+4], второй как word[bp+6] и т. д. Представляется важным отметить,
что перед возвратом из процедуры необходимо восстановить значение BP из стека.
7.5. Использование стека процессором при возврате
Извлечение параметров из стека
После того, как процедура выполнилась, необходимо очистить стек, вы-
толкнув из него параметры. Тут тоже существует 2 способа: стек может быть очищен самой процедурой или кодом, который эту процедуру вызывал. Для первого способа используется команда RET с одним операндом, который должен быть равен количеству байтов, выталкиваемых из стека (рис. 32). В
нашем случае он должен быть равен количеству параметров, умноженному на 2.
Для второго способа нужно использовать команду RET без операндов.
Стек восстанавливается после выполнения процедуры путем прибавления значения к SP. С помощью такого способа программируются процедуры с переменным количеством параметров. Процедура не знает, сколько ей будет передано параметров, поэтому очистка стека должна выполняться вызываю-
щим кодом.
82
|
push [arg1] |
push [arg1] |
|
push [arg0] |
push [arg0] |
|
call myproc |
call myproc2 |
|
... |
add sp,4 |
;------------------------------ |
|
;Восстановление указа- |
---------------- |
|
теля стека |
;Процедура c двумя па- |
... |
|
|
раметрами |
;------------------------------ |
|
myproc: |
------------------ |
|
push bp |
;Процедура с двумя па- |
|
mov bp,sp |
раметрами (не очищает |
|
... |
стек) |
|
pop bp |
myproc2: |
ret 4 |
;Из стека до- |
push bp |
полнительно извлекает- |
mov bp,sp |
|
|
ся 4 байт |
... |
|
|
pop bp |
|
|
ret |
Рис. 32. Извлечение параметров из стека
7.6. Стековая адресация
Соглашения вызова
Совокупность таких особенностей, как способ и порядок передачи пара-
метров, механизм очистки стека, сохранение определенных регистров в про-
цедуре и некоторых других, называется соглашениями вызова. Соблюдение этих соглашений является важным, если вы из своей программы обращаетесь к компонентам, написанным на других языках программирования, вызываете функции операционной системы (ОС), или хотите из других языков вызывать процедуры, написанные на Assembler.
В качестве примера рассмотрим процедуру с тремя параметрами: a, b и c. Процедура вычисляет значение выражения (a+b)/c. На рис. 33 представлен листинг для данной процедуры на языке Assembler. Параметры передаются через стек в обратном порядке, результат возвращается в регистр AX, стек восстанавливается вызываемой процедурой. Все числа – 16-битные целые со знаком. Главное – не запутаться со смещениями относительно BP.
83
use16 |
;Генерировать 16-битный код |
||
org 100h |
;Программа начинается с адреса 100h |
||
jmp start |
;Переход на метку start |
||
;--------------------------------------------------------------------- |
|
|
|
|
; Данные |
|
|
|
a |
dw 81 |
|
|
b |
dw 273 |
|
|
x |
dw ? |
|
;--------------------------------------------------------------------- |
|
|
|
|
|
start: |
|
|
push 3 |
|
;c=3 |
|
push [b] |
;b |
|
|
push [a] |
;a |
|
call primer |
;Вызов процедуры |
||
|
mov [x],ax |
|
;x=(a+b)/c |
|
mov ax,4C00h |
;\ |
|
int 21h |
;/ Завершение программы |
||
;---------------------------------------------------------------------
;Процедура c тремя параметрами: a, b, c.
;Вычисляет значение выражения (a+b)/c. Результат возвращается в
|
|
AX. |
|
|
|
primer: |
|
push bp |
;Сохранение регистра BP |
||
|
|
mov bp,sp |
;BP=SP |
|
|
push dx |
|
|
|
mov ax,[bp+4] |
;AX=a |
|
add ax,[bp+6] |
;AX=(a+b) |
|
|
cwd |
;DX:AX=(a+b) |
|
|
idiv word[bp+8] |
;AX=(a+b)/c |
|
|
|
pop dx |
|
pop bp |
|
;Восстановление регистра BP |
|
ret 6 |
;Возврат с извлечением параметров из стека |
||
Рис. 33. Стековая
адресация
8. Модели памяти. Плоская, сегментная (многосегментная) модели и модель памяти в реальном режиме. «Нереальный» режим
8.1. Плоская модель памяти
При использовании средств процессора для управления памятью про-
грамма может использовать одну из трех моделей доступа к памяти, такие как сплошная («плоская») модель памяти, сегментированная модель памяти и модель режима реального адреса.
При использовании сплошной модели (Flat Model) памяти программа оперирует единым непрерывным адресным пространством – линейным ад-
ресным пространством. В нем содержатся и код, и стек, и данные програм-
84
мы, адресуемые смещением в пределах от 0 до 232-1. Такое 32-битное сме-
щение называется линейным адресом (рис. 34).
Идеология плоской модели заключается в том, что вся память представ-
ляет собой единую линейную последовательность байтов.
Рис. 34. Плоская (сплошная)
модель памяти
Ответственность за корректное использование памяти целиком ложится на прикладного программиста, т. е. он должен позаботиться о том, чтобы данные не затерли коды или на них не «наехал» растущий стек. Для 16-
битных процессоров плоская модель памяти позволяет адресовать 64 кБ опе-
ративной памяти, для 32-битных процессоров – 4 ГБ, для 64-битных – 16 эк-
забайт.
Важно отметить, что плоская модель не может быть использована в ре-
альном режиме – в ней не вся адресуемая память будет доступной. Чтобы по-
лучить плоскую модель памяти, достаточно все сегментные регистры загру-
зить селектором дескриптора, описывающим одну и ту же область памяти, но с разными свойствами для кода, стека и данных (рис. 35).
85
Рис. 35. Получение
плоской модели памяти
Преимущества управления памятью с плоской моделью:
1. В одном из многозадачных встроенных приложений, где управление памятью не нужно и не желательно, модель обеспечивает простейший ин-
терфейс для программирования, с прямым доступом ко всем местам в памяти и минимальной сложностью конструкции программы.
2. При многозадачности и распределении ресурсов плоская модель по-
прежнему обеспечивает максимальную гибкость для реализации этого типа управления памятью.
Управление памятью все еще реализуется на основе плоской модели, в
целях содействия функциональности операционной системы, защиты ресур-
сов, многозадачности или увеличения объема памяти за пределы ограниче-
ний, налагаемых физическим адресным пространством процессора.
8.2. Сегментированная модель памяти
При использовании сегментированной модели (Segmented Model) для программы память представляется группой независимых адресных блоков,
называемых сегментами.
8.2.1. Односегментная модель
Операционные системы, поддерживающие односегментную модель «в
чистом виде», могут быть частным решением какого-нибудь отдельного про-
граммиста, решившего написать ОС для своих целей (например, в рамках тренировки написания ОС, как рекомендовано в [6]). Что, в свою очередь,
облегчит понимание более сложных моделей.
Внешне (с точки зрения программиста) эта модель очень похожа на мо-
дель с фиксированными разделами: программа-процесс готовится в плоском
86
виртуальном адресном пространстве. Процесс занимает непрерывное про-
странство виртуальной памяти, и в реальную память он также загружается в один непрерывный раздел (сегмент). Сегмент может начинаться с любого ад-
реса реальной памяти и иметь любой раздел, не превышающий, однако, раз-
мера реальной памяти.
Существенное отличие сегментной модели состоит в том, что она ис-
пользует аппаратную динамическую трансляцию адресов. Загруженный в ре-
альную память и выполняющийся процесс продолжает обращаться к памяти,
используя виртуальные адреса, и лишь при каждом конкретном обращении виртуальный адрес аппаратно переводится в реальный. В вычислительной системе, поддерживающей односегментную модель, должен существовать регистр дескриптора сегмента, содержимое которого состоит из двух полей:
начального (базового) адреса сегмента в реальной памяти и длины сегмента.
Когда процесс размещается в памяти, для выделенного ему сегмента формируется дескриптор, который записывается в вектор состояния в кон-
тексте процесса. При переключении контекста дескриптор сегмента загружа-
ется в аппаратный регистр дескриптора сегмента и служит той «таблицей трансляции», по которой аппаратура переводит виртуальные адреса в реаль-
ные. Сама трансляция адресов происходит по простейшему алгоритму. По-
скольку виртуальное адресное пространство процесса представляет собой линейную последовательность адресов, начинающуюся с 0, виртуальный ад-
рес является простым смещением относительно начала сегмента. Реальный адрес получается сложением виртуального адреса с базовым адресом, вы-
бранным из дескриптора сегмента. Единственный путь для выхода процесса за пределы своего виртуального адресного пространства – задание виртуаль-
ного адреса, большего, чем размер сегмента. Этот путь легко может быть пе-
рекрыт, если аппаратура при трансляции адресов будет сравнивать виртуаль-
ный адрес с длиной сегмента и выполнять прерывание-ловушку, если вирту-
альный адрес больше.
87
То обстоятельство, что процесс работает в виртуальных адресах, делает
возможным перемещение сегментов в реальной памяти. Переместив процесс
вдругую область реальной памяти, ОС просто изменяет поле базового адреса
вдескрипторе его сегмента. Поскольку, как и в модели с фиксированными разделами, реальная память распределяется непрерывными блоками пере-
менной длины, здесь применяются те же стратегии размещения. Но возмож-
ное здесь перемещение сегментов является эффективным способом борьбы с внешними дырами. Сегменты переписываются в реальной памяти таким об-
разом, чтобы свободных мест между ними не оставалось, все свободное про-
странство сливается в один большой свободный блок и, таким образом, ока-
зывается доступным для последующего распределения.
Другой возможностью, которую открывает динамическая трансляция адресов, является вытеснение сегментов. Если даже после перемещения сег-
ментов запрос на память не может быть удовлетворен, то ОС может перепи-
сать какой-либо сегмент на внешнюю память и освободить занимаемую им реальную память. Поскольку контекст процесса, который содержится в вы-
тесненном сегменте, сохраняется, то впоследствии ОС может вновь загрузить этот сегмент в реальную память, откорректировать базовый адрес в его деск-
рипторе и возобновить выполнение процесса. Перемещение сегментов и (см.
ниже) страниц между оперативной и внешней памятью и наоборот называет-
ся свопингом (swapping), а составные его части – вытеснением (swap out) и
подкачкой (swap in). Поскольку в модели происходит вытеснение сегментов,
должна быть реализована какая-то его стратегия. Естественно, что наилуч-
шим кандидатом на вытеснение должен быть сегмент процесса, находящего-
ся в заблокированном состоянии. Но следует при этом иметь в виду, что про-
цесс может быть заблокирован потому, что он ожидает завершения операции ввода-вывода. При вводе-выводе, использующем канал или прямой доступ к памяти, аппаратура ввода-вывода не выполняет трансляцию адресов (см. гла-
ву 6), а производит обмен данными с областью памяти, реальный адрес кото-
рой был задан ей при инициировании операции. Сегмент, участвующий в та-
88
кой операции ввода-вывода, должен быть заблокирован не только от вытес-
нения, но и от перемещения в реальной памяти. (Эти же соображения долж-
ны учитываться и в других моделях памяти). При отсутствии подходящих кандидатов на вытеснение в очереди заблокированных процессов жертва может быть выбрана из очереди готовых процессов. Естественно назначить жертвой процесс, имеющий самый низкий приоритет у планировщика про-
цессов. Но если брать этот приоритет единственным критерием, то имеется потенциальная опасность возникновения избыточных перемещений. Про-
цесс, имеющий низкий приоритет, может быть несколько раз вытеснен и вновь подкачан, но между всеми подкачками и вытеснениями может так и не получить ни одного кванта обслуживания на центральном процессоре. В сис-
темах с динамическими приоритетами процесс (например, Unix), подкачан-
ный в оперативную память защищается от вытеснения некоторой временной выдержкой, в течение которой он имеет шанс повысить свой приоритет и по-
лучить квант обслуживания. Также и вытесненный процесс должен быть не-
которое время выдержан на внешней памяти, прежде чем он может быть подкачан. В системах со статическими приоритетами приоритет процесса у планировщика определяет и его приоритет в очереди к ресурсу реальной па-
мяти.
Процесс, работающий в односегментной модели памяти, имеет возмож-
ность динамически изменять размер своего виртуального адресного про-
странства. При выполнении такого запроса от процесса ОС просто изменяет поле длины в дескрипторе его сегмента, если в реальной памяти вслед за сегментом процесса имеется свободный участок достаточного размера. Если же такого участка нет, ОС может переместить процесс или заблокировать его в ожидании освобождения ресурса.
Для адресации байта памяти программа должна использовать
логический адрес, состоящий из селектора сегмента и смещения.
89
Селектор сегмента выбирает определенный сегмент, а смеще-
ние указывает на конкретный байт в адресном пространстве выбранно-
го сегмента.
Каждая задача в защищенном режиме может иметь до 16 383
сегментов, размером до 4 Гбайт каждый, таким образом, общий объем памяти, адресуемой программой, составляет 64 Тбайт.
8.2.2. Многосегментная модель памяти
Расширим модель, рассмотренную в предыдущем разделе, на случай N
сегментов.
Виртуальное пространство процесса разбивается на сегменты, которые нумеруются от 0 до N-1. Виртуальный адрес, таким образом, состоит из двух частей: номера сегмента и смещения в сегменте. Эти части могут либо пред-
ставляться по отдельности каждая, либо упаковываться в одно адресное сло-
во, в котором определенное число старших разрядов будет интерпретиро-
ваться как номер сегмента, а оставшаяся часть – как смещение. В первом случае сегменты могут размещаться произвольным образом в виртуальном адресном пространстве. Во втором случае создается впечатление плоского адресного пространства с адресами от 0 до максимально возможного при данной разрядности виртуального адреса, но в этом пространстве могут быть дыры – виртуальные адреса, для процесса недоступные, – из-за отсутствия соответствующих сегментов или из-за сегментов, длина которых меньше максимально возможной.
Количество сегментов и максимальный размер сегмента ограничиваются аппаратурой – разрядностью полей адресного слова. При выделении процес-
су реальной памяти каждый сегмент размещается в непрерывной области ре-
альной памяти, но сегменты, смежные в виртуальной памяти, могут попадать в несмежные области памяти реальной. Теперь для процесса уже недостаточ-
но одного дескриптора сегмента – он должен иметь таблицу таких дескрип-
торов в составе своего блока контекста. Аппаратный регистр дескриптора
90
