Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
КНИГА_АСМ ассемблер.doc
Скачиваний:
61
Добавлен:
19.11.2019
Размер:
732.16 Кб
Скачать

2.4. Оперативная память.

С точки зрения программиста оперативная память представляет собой линейный массив ячеек, размером один байт каждая. Каждой ячейке ставится в соответствие ее адрес (номер). Этот адрес принято называть абсолютным или физическим (принятое обозначение – Аф). Считается что адреса ячеек памяти, с которой работает DOS, лежат в диапазоне от 00000h до fffffh, как показано на рис 2.1. То есть DOS работает с памятью объемом 1 Мбайт.

Рис. 2.1

Чтобы прочитать байт информации из какой-то ячейки памяти или записать в эту ячейку новый байт, необходимо написать соответствующую команду и в этой команде задать необходимый адрес. Например, если в результате выполнения команды формируется физический адрес 00000h, процессор обращается к младшему байту памяти.

Информация в памяти может располагаться не только в виде отдельных байт, но и в виде слов (2 смежных байта), двойных слов (4 байта) и. т. д. При этом, адресом любой структуры в памяти считается физический адрес младшего байта этой структуры. То есть если слово занимает в памяти два байта с адресами 0002аh и 0002bh, это слово имеет физический адрес 0002ah.

2.5. Стек

Стек – это особый вид памяти. Если при обращении к обычной памяти мы должны тем или иным образом задавать в команде адрес ячейки, к которой мы обращаемся, то при обращении к стеку, никакие адреса в команде не задаются. Для того чтобы это было возможно в состав процессора введен специальный регистр sp, называемый указателем стека. Содержимое этого регистра и адресует некоторую ячейку памяти, которую называют вершиной стека. При выполнении стековой операции (команды), процессор берет из sp адрес вершины стека и записывает в нее (или считывает из нее) информацию. При этом процессор автоматически изменяет содержимое sp, изменяя тем самым месторасположение вершины стека.

Собственно существует две стековых операции:

  • затолкнуть информацию в стек (push)

  • вытолкнуть информацию из стека (pop).

Например, команда push bx (затолкнуть в стек содержимое двухбайтового регистра bx) выполняется следующим образом. Сначала процессор вычтет из содержимого регистра sp двойку (поскольку формат bx2 байта), изменив тем самым вершину стека, а затем в эту новую вершину загрузит содержимое регистра bx. Таким образом, при заталкивании стек растет в сторону младших адресов памяти.

Команда pop bx (вытолкнуть слово из вершины стека в регистр bx) выполняется в обратном порядке. Сначала процессор по содержимому sp определит вершину стека, считает из этой вершины слово и поместит его в bx, а затем прибавит к sp двойку, изменив тем самым вершину стека.

Приведем пример. Состояние стека на данный момент приведено на рис. 2.2.

00

00

00

00

00

00

sp

43h

15h

Рис. 2.2

Пусть в данный момент содержимое bx = 35c7h, а содержимое ax = 2233h. И пусть выполняется последовательность команд:

push bx

push ax

pop bx

Состояние стека и регистров, после выполнения каждой команды показано соответственно на рис. 2.3-2.5.

00

00

00

00

sp

с7h

35h

43h

15h

bx = 35c7h ax = 2233h

Рис. 2.3.

00

00

sp

33h

22h

с7h

35h

43h

15h

bx = 35c7h ax = 2233h

Рис. 2.4

00

00

33h

22h

sp

с7h

35h

43h

15h

bx = 2233h ax = 2233h

Рис. 2.5

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

  • call - вызов подпрограммы (запоминает в стеке адрес возврата);

  • ret - возврат из подпрограммы (берет из стека адрес возврата);

  • int n – программное прерывание (запоминает в стеке адрес возврата и регистр флагов);

  • iret -возврат из прерывания (выталкивает из стека адрес возврата и восстанавливает флаги).

Стек очень удобно использовать, когда надо на время сохранить, а затем восстановить содержимое какого-либо регистра.

Самая распространенная ошибка при написании стековых команд заключается в использовании восьмиразрядных регистров, что не допускается системой команд. Со стеком всегда обмениваются словами, а не байтами. Например, команда push cx вполне допустима, а на команде push cl транслятор выдаст сообщение об ошибке.

Другая ошибка, не столь очевидная, но приводящая к куда более тяжелым последствиям, заключается в том, что программист не следит за положением указателя стека, а это его прямая обязанность. Если sp указывает не туда, куда рассчитывает программист, то команда, выталкивающая что-либо из стека, приведет к непредсказуемым для этого программиста последствиям.

Собственно, работая со стеком, полезно помнить два простых правила:

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

  2. Если Вы последовательно затолкнули в стек содержимое ряда регистров, то восстанавливать эти регистры из стека надо в обратном порядке. Например:

push dx

push bx

push cx

.

.

.

pop cx

pop bx

pop dx