Материал: 1117

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Один из полезных способов передачи параметров в подпрограмму

состоит в занесении

параметров в стек (см. уч. пос., ч.6). Стек находится в

сегменте, на который указывает регистр ss.

push bp

; сохранить содержимое регистра bp в стек

mov

bp,sp

; загрузка в ax первого параметра, передаваемого

mov

ax,[bp+4]

; при вызове подпрограммы на ассемблере.

4.16. Регистр sp

Регистр sp называется также указателем стека, он в каждый момент времени указывает на вершину стека. Вершина стека – это то место, в котором в стеке сохраняется помещаемое туда значение. Занесение значений в стек выполняется инструкцией push. Извлечение значений из стека выполняется инструкцией pop.

Рассмотрим, как изменяются регистры sp, ax и bp по мере выполнения следующего кода:

mov

ax,1

; ax:=1

push ax

; в стек заносится 1, и sp уменьшается на 2;

mov

bx,2

; bx := 2

push bx

; в стек заносится 2, и sp уменьшается на 2

pop

ax

; ax := 2, и sp увеличивается на 2

pop

bx

; bx := 1, и sp увеличивается на 2

Хотя процессор 8086 и позволяет записывать значения в sp или складывать и вычитать хранящиеся в регистре sp значения (как с регистрами общего назначения), лучше этого не делать!

Если вы измените sp, даже на несколько инструкций, то правильное значение стека может оказаться недоступным, когда оно потребуется системным ресурсам. Можно выполнять операции занесения в стек и извлечения из него, вызовы и возвраты управления, но не изменяйте значения регистра sp непосредственно.

4.17. Указатель инструкций (регистр ip)

Регистр ip всегда содержит смещение в памяти, по которому хранится следующая выполняемая инструкция.

cs

 

Сегмент кода

ip

 

 

 

 

 

 

 

Команда

 

 

 

 

 

 

 

Рис. 4.3

После выполнения инструкции указатель обычно перемещается на следующую за ней инструкцию, но некоторые инструкции (к ним

26

относятся вызовы процедур – call, переходы – jmp и jcc, циклы – loop, возврат из процедур – ret) могут привести к тому, что в ip будет загружено новое значение и выполнен переход на другой участок программы.

Значение регистра ip нельзя прочитать или записать непосредственно. Базовый адрес хранится в регистре cs, при этом указатель инструкций

задает смещение относительно этого базового адреса.

4.18. Сегментные регистры

Наиболее необычный аспект процессора 8086 – сегментация памяти. Предпосылкой сегментации является то, что процессор 8086 может адресоваться к 1 мегабайту памяти, а для этого необходимы 20-разрядные сегментные регистры.

Для формирования 20-разрядного адреса памяти процессор 8086 использует двухступенчатую схему адресации: каждый 16-разрядный указатель памяти или смещение комбинируется с содержимым соответствующего 16-разрядного сегментного регистра.

Для этого значение сегмента сдвигается влево на 4 (то есть умножается на 16), а затем складывается со смещением.

Рассмотрим, например, следующий фрагмент программы:

mov

ax,1000h

 

mov

ds,ax

; загрузка в ds значения 1000h

mov

si,201h

; загрузка в si значения 201h

mov

dl,[si]

 

Регистры ds и si можно представить в виде "сегмент:смещение" – 1000:201h. Адрес, из которого загружаются данные, представляет собой

((ds * 16) + si )

или

((1000h * 16) + 201h)

ds

 

 

Сегмент данных

 

si

 

 

 

 

 

 

 

 

 

 

 

Данные

 

 

 

 

 

 

 

 

 

Рис. 4.4

Программа получает доступ к полному адресному пространству в 1Мб только при использовании пары "сегмент:смещение".

Все инструкции и режимы адресации процессора 8086 по умолчанию работают относительно того или иного сегментного регистра, хотя в некоторых инструкциях можно явно указать желаемый сегментный регистр (см. реализацию передачи параметра в потоке кода в уч.пос., ч.6 и реализацию таблицы перехода в уч.пос., ч.7).

27

Редко требуется загружать значение непосредственно в сегментный регистр (например, как это показано выше – значение 1000h). Чаще бывает нужно загружать в сегментные регистры имена сегментов, которые в ходе ассемблирования, компоновки и выполнения превращаются в числа.

Наиболее общим именем сегмента является @date, которое в упрощенных директивах определения сегментов используется для ссылки на используемый по умолчанию сегмент данных (см. уч. пос., ч.4).

Только блок памяти размером в 64 Кб может адресоваться через сегментный регистр, так как это максимальный объем памяти, к которой можно адресоваться с помощью 16-битового смещения. Это может оказаться неудобным при работе с большим (более 64 Кб) объемом памяти, так как и значение сегментного регистра, и смещение придется часто изменять.

Кроме того, единственная операция, которую можно выполнять с сегментными регистрами, состоит в копировании значений между сегментным регистром и каким-либо общим регистром или стеком (п. 4.72). Например, чтобы добавить значение 100 к регистру es, требуется следующее:

mov ax,es add ax,100 mov es,ax

Второй момент: каждая ячейка памяти адресуется через многие сочетания "сегмент:смещение". Например, адрес памяти 100h образуется с помощью следующих значений "сегмент:смещение": 0:100h, 1:f0h, 2:e0h и т.д., так как при вычислении всех этих пар "сегмент:смещение" получается значение адреса 100h.

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

4.19. Регистр cs

Регистр cs указывает сегмент кода, в котором находится следующая выполняемая инструкция. Она находится (рис. 4.5) по смещению, определяемому в сегменте кода регистром ip, на нее указывает адрес cs:ip.

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

cs

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

ip

Рис. 4.5

28

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

Никакие другие режимы адресации и никакие указатели памяти, отличные от ip, не могут нормально работать относительно регистра cs.

4.20. Регистр ds

Регистр ds указывает на начало сегмента данных, в котором находится большинство размещенных в памяти операндов. Обычно для ссылки на адреса памяти используются смещения, предполагающие использование регистров bx, si или di. Сегмент данных – это сегмент, в котором находится текущий набор данных.

ds

Сегмент данных

si

Данные

di

Данные

bx

Данные

Рис. 4.6

4.21. Регистр es

Регистр es указывает на начало блока памяти объемом 64 Кб, который называется дополнительным сегментом.

es

Дополнительный

сегмент данных

di

Данные

Рис. 4.7

Дополнительный сегмент доступен тогда, когда в нем возникает необходимость. Иногда он используется для выделения дополнительного

29

блока памяти объемом 64 Кб для данных. Однако доступ к памяти в дополнительном сегменте менее эффективен, чем доступ к памяти в сегменте данных.

Особенно полезен дополнительный сегмент, когда используются строковые инструкции. Все строковые инструкции, которые выполняют запись в память, используют (рис. 4.7) в качестве адреса памяти, в которую нужно выполнить запись, пару регистров es:di.

Это означает, что регистр es особенно полезен при копировании блоков, сравнении строк, просмотре памяти и очистке блоков памяти.

4.22. Регистр ss

Регистр ss указывает на начало сегмента стека, т.е. на блок памяти объемом до 64 Кб, в котором находится стек. Все инструкции, которые неявно используют регистр sp (включая занесение в стек, извлечение из стека, вызовы и возвраты управления), работают с сегментом стека, так как только регистр sp может использоваться для адресации памяти в сегменте стека.

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

ss

 

 

 

Сегмент стека

 

 

 

 

 

 

sp

 

 

 

Данные

bp

Данные

Рис. 4.8

4.23.Директивы определения сегментов

Вассемблере предусмотрены два набора директив управления сегментами:

1) из упрощенных директив определения сегментов (делает управление сегментами относительно легким и идеально подходит для компоновки модулей ассемблера с языками высокого уровня, но поддерживает только некоторые из сегментных средств, имеющихся в ассемблере);

30

Источник: https://studfile.net/preview/16407174/