Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Абель.docx
Скачиваний:
19
Добавлен:
26.11.2018
Размер:
569.84 Кб
Скачать

Ip: Нуль.

SS: Адрес сегмента стека.

SP: Относительный адрес, указывающий на вершину стека. Например, для

стека в 32 слова (64 байта), определенного как

DW 32 DUP(?)

SP содержит 64, или шест.40.

Выполним трассировку простой EXE-программы, приведенной на рис.7.4.

На практике вызываемые процедуры содержат любое число команд.

__________________________________________________________________________

TITLE CALLPROC (EXE) Вызов процедур

0000 STACKSG SEGMENT PARA STACK 'Stack'

0000 20 [ ???? ] DW 32 DUP(?)

0040 STACKG ENDS

0000 CODESG SEGMENT PARA 'Code'

0000 BEGIN PROC FAR

ASSUME CS:CODESG,SS:STACKSG

0000 1E PUSH DS

0001 2B C0 SUB AX,AX

0003 50 PUSH AX

0004 E8 0008 R CALL B10 ;Вызвать B10

; ...

0007 CB RET ;Завершить программу

0008 BEGIN ENDP

;-------------------------------------

0008 B10 PROC

0008 E8 000C R CALL C10 ;Вызвать C10

; ...

000B C3 RET ;Вернуться в

000C B10 ENDP ; вызывающую программу

;---------------------------------------------

000C C10 PROC

; ...

000C C3 RET ;Вернуться в

000D C10 ENDP ; вызывающую программу

;---------------------------------------------

000D CODESG ENDS

END BEGIN

__________________________________________________________________________

Рис.7.4. Воздействие выполнения программы на стек.

Текущая доступная ячейка стека для занесения или извлечения слова

является вершина стека. Первая команда PUSH уменьшает значение SP на 2 и

заносит содержимое регистра DS (в данном примере 049f) в вершину стека,

т.е. по адресу 4B00+3E. Вторая команда PUSH также уменьшает значение SP на

2 и записывает содержимое регистра AX (0000) по адресу 4B00+3C. Команда

CALL B10 уменьшает значение SP и записывает относительный адрес следующей

команды (0007) в стек по адресу 4B00+3A. Команда CALL C10 уменьшает

значение SP и записывает относительный адрес следующей команды (000B) в

стек по адресу 4B00+38.

При возврате из процедуры C10 команда RET извлекает 000B из стека

(4B00+38), помещает его в указатель команд IP и увеличивает значение SP на

2. При этом происходит автоматический возврат по относительному адресу

000B в кодовом сегменте, т.Е. В процедуру b10.

Команда RET в конце процедуры B10 извлекает адрес 0007 из стека

(4B00+3A), помещают его в IP и увеличивает значение SP на 2. При этом

происходит автоматический возврат по относительному адресу 0007 в кодовом

сегменте. Команда RET по адресу 0007 завершает выполнение программы,

осуществляя возврат типа FAR.

Ниже показано воздействие на стек при выполнении каждой команды. Для

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

содержимое памяти с адреса 0034 до 003F и содержимое регистра SP:

Команда Стек SP

Начальное значение: хххх хххх хххх хххх хххх хххх 0040

PUSH DS (запись 049F) хххх хххх хххх хххх хххх 049F 003E

PUSH AX (запись 0000) хххх хххх хххх хххх 0000 049F 003C

CALL B10 (запись 0007) хххх хххх хххх 0700 0000 049F 003A

CALL C10 (запись 000B) хххх хххх 0B00 0700 0000 049F 0038

RET (выборка 000B) хххх хххх хххх 0700 0000 049F 003A

RET (выборка 0007) хххх хххх хххх хххх 0000 049F 003C

| | | | | |

Смещение в стеке: 0034 0036 0038 003A 003C 003E

Обратите внимание на два момента. Во-первых, слова в памяти содержат

байты в обратной последовательности, так 0007 записывается в виде 0700.

Во-вторых, отладчик DEBUG при использовании его для просмотра стека

заносит в стек другие значения, включая содержимое IP, для собственных

нужд.

ПРОГРАММА: РАСШИРЕННЫЕ ОПЕРАЦИИ ПЕРЕСЫЛКИ

________________________________________________________________

В предыдущих программах были показаны команды пересылки

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

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

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

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

непосредственно другую область. В данном разделе объясняется процесс

пересылки данных, которые имеют длину более двух байт. В гл.11 будет

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

области памяти непосредственно в другую область.

В EXE-программе, приведенной на рис.7.5, сегмент данных cодержит три

девятибайтовых поля, NAME1, NAME2, NAME3. Цель программы - переслать

данные из поля NAME1 в поле NAME2 и переслать данные из поля NAME2 в поле

NAME3. Так как эти поля имеют длину девять байт каждая, то для пересылки

данных кроме простой команды MOV потребуются еще другие команды. Программа

содержит несколько новых особенностей.

__________________________________________________________________________

page 65,132

TITLE EXMOVE (EXE) Операции расширенной пересылки

;------------------------------------------------------

STACKSG SEGMENT PARA STACK 'Stack'

DW 32 DUP(?)

STACKSG ENDS

;------------------------------------------------------

DATASG SEGMENT PARA 'Data'

NAME1 DB 'ABCDEFGHI'

NAME2 DB 'JKLMNOPQR'

NAME3 DB 'STUVWXYZ*'

DATASG ENDS

;-------------------------------------------------------

CODESG SEGMENT PARA 'Code'

BEGIN PROC FAR

ASSUME CS:CODESG,DS:DATASG,SS:STACKSG,ES:DATASG

PUSH DS

SUB AX,AX

PUSH AX

MOV AX,DATASG

MOV DS,AX

MOV ES,AX

CALL B10MOVE ;Вызвать JUMP подпрограмму

CALL C10MOVE ;Вызвать CALL подпрограмму

RET ;Завершить программу

BEGIN ENDP

; Расширенная пересылка (JUMP-подпрограмма),

; использующая переход по условию:

; -----------------------------------------

B10MOVE PROC

LEA SI,NAME1 ;Инициализация адресов

LEA DI,NAME2 ; NAME1 и NAME2

MOV CX,09 ;Переслать 9 символов

B20:

MOV AL,[SI] ;Переслать из NAME1

MOV [DI],AL ;Переслать в NAME2