На главную Назад
Добро пожаловать, уважаемый посетитель!

В гл.3 обсуждалось, как реализован стек в микропроцессоре 8088.

Микропроцессор 8088 адресует стек с помощью регистровой пары SS:SP.

Помещение объектов в стек приводит к тому, что он растет в сторону

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

запоминания адресов возврата из подпрограмм.В этом разделе

рассматриваются некоторые команды, которые непосредственно работают

со стеком.

 

Фиг.4.7 иллюстрирует ассемблированные стековые команды.

Мнемоника команд очевидна; за кодами операций PUSH и POP следует

имя регистра для указания операнда. Единственным исключением

является помещение и извлечение из стека регистра флагов, которые

используют мнемонику PUSHF и POPF соответственно. Содержимое любой

ячейки памяти, которую программа может адресовать, используя

возможные способы адресации, также может быть помещено или

извлечено из стека.

 

При любых действиях со стеком в микропроцессоре 8088 базовой

единицей информации является 16=битовое слово. Длина любого

объекта, помещаемого в стек либо извлекаемого из стека, составляет

одно или несколько слов. Байтовых команд, связанных с засылкой

данных или извлечением их из стека, не существует. Если, например,

программе необходимо сохранить содержимое регистра AL а стеке, она

должна поместить содержимое регистра AX, так как не существует

способа сохранения только содержимого регистра AL.

 

Основное назначение стека - временное хранение информации. Как

мы уже видели, стек используется для сохранения адреса возврата;

программа также может сохранять данные. Если программа хочет

использовать регистр, пусть даже сохранить текущие данные, она

может послать значение этого регистра в стек. Эти данные

сохраняются в стеке и позже могут быть восстановлены. Например,

Microsoft (R) Macro Assembler Version 5.001/1/80 04:00:43

Фиг. 4.7 Операции со стеком Page1-1

 

 

PAGE,132

TITLEФиг. 4.7 Операции со стеком

0000CODESEGMENT

ASSUMECS:CODE,DS:CODE

0000EXWORDLABELWORD

 

000050PUSHAX ; Поместить регистр в стек

000156PUSHSI

00020EPUSHCS ; Можно поместить в стек сегментный регистр

0003FF 36 0000 RPUSHEXWORD; Можно также поместить в стек ячейку памяти

 

00078F 06 0000 RPOPEXWORD; Можно извлечь то, что в помещено в стек

000B07POPES ; Можно извлечь в другое место

000C5FPOPDI

000D5BPOPBX

 

000E9CPUSHF; Другая мнемоника для флагов

000F9DPOPF

 

;-----Пример, демонстрирующий передачу параметров

 

001050PUSHAX

001153PUSHBX

001251PUSHCX

001352PUSHDX

0014E8 0017 RCALLSUBROUTINE; Передача управления

;...; Продолжение программы

 

0017SUBROUTINEPROCNEAR

 

00178B ECMOVBP, SP; Занесение в BP адреса стека

00198B 46 02MOVAX, [BP+2]; Выборка последнего параметра (DX)

001C8B 5E 04MOVBX, [BP+4]; Выборка третьего параметра (CX)

001F8B 4E 06MOVCX, [BP+6]; Выборка второго параметра (BX)

00228B 56 08MOVDX, [BP+8]; Выборка первого параметра (AX)

;...

0025C2 0008RET8; Возврат с уничтожением поля параметров

0028SUBROUTINEENDP

0028CODEENDS

END

 

Фиг. 4.7 Операции со стеком

 

программе нужно ввести код из порта ввода=вывода 3DAH, а в регистре

DX находятся важные данные. Следующая последовательность команд

 

PUSHDX

MOV DX,3DAH

INAL,DX

POP DX

 

сохраняет регистр DX в стеке на то время, пока он нужен в

программе для выполнения команды IN.

 

Операции сохранения регистров в стеке обычно используется в

начале программы. В большинстве случаев подпрограмма старается

избегать изменения содержимого любого регистра. Поэтому

подпрограмма, которой нужны регистры для вычислений и для хранения

адресов, помещает все необходимые ей регистры в стек до выполнения

команд обработки. Затем, после выполнения, подпрограмма

восстанавливает регистры из стека с помощью команд POP.

 

Помните о том, что стек - это структура типа LIFO. Если в вашей

программе выполняется последовательность команд

 

PUSHBX

PUSH CX

POP BX

POP CX

 

то результирующим эффектом будет обмен значений в регистрах BX

и CX. Только тот факт, что в команде PUSH был указан регистр BX, не

означает, что команда POP, указывающая на тот же регистр,

восстанавливает первоначальное содержимое регистра BX. Еще одним

важным моментом является то, что команды PUSH и POP должны быть

сбалансированы, т.е. каждой команде PUSH должна соответствовать

команда POP. Точно так же, как и в случае скобок в арифметическом

выражении, если посылки и извлечения из стека не сбалансированы,

результаты будут неверны. Более того, несбалансированные команды

PUSH/POP обычно приводят к возврату из подпрограмм по адресу

значения данных, а не значения указателя команд из=за того, что

микропроцессор 8088 записывает в стек адрес возврата. Обычно это

вынуждает микропроцессор выполнять программу, которую программист

никогда не писал. Поэтому баланс стековых команд обязателен. Будьте

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

переход вокруг стековых операций; можно легко выпустить из виду

один из вариантов выполнения, что оставит стек несбалансированным.

 

Наряду с сохранением данных, программа может использовать стек

в качестве буфера при некоторых пересылках; в частности, не

существует команды пересылки, которая бы переносила данные из

одного сегментного регистра в другой. В обычном случае загрузка

одного сегментного регистра из другого требует сначала загрузки его

значения а промежуточный регистр. Это достигается следующей

последовательностью из двух команд:

 

MOVAX,CS;переслать значение регистра

;CS в регистр AX

MOVDS,AX;загрузить это значение в

; регистр DS

 

Каждая из этих команд имеет длину несколько байт, и эта

последовательность разрушает содержимое регистра AX. Альтернативным

подходом может быть

 

PUSHCS; регистр CS поместить в стек

POPDS; поместить это значение в регистр DS

 

Результирующий эффект этой последовательности команд тот же,

регистр DS загружается из регистра CS. Здесь длина программы -

всего два байта, и к тому же не требуется промежуточный регистр.

Однако эти две команды занимают больше времени, так как нужны

дополнительные циклы чтения и записи в стек. Это - метод потери в

скорости выполнения ради уменьшения размера объектного кода.


 

Mail.ru