Регистр SP


Регистр SP называется также указателем стека. Это «наименее общий» из регистров общего назначения, поскольку он практически всегда используется для специальной цели обеспечения стека. Стек это область памяти, в которой можно сохранять значения и из которой они могут затем извлекаться по дисциплине «последнийпришелпервыйушел» (FIFO). То есть последнее сохраненное в стеке значение будет первым значением, которое вы получите при чтении из стека. Классической аналогией стека является стопка тарелок. Поскольку тарелки можно класть столько сверху стопки (и брать также), то первая положенная тарелка будет последней, которую вы сможете взять.

Регистр SP в каждый момент времени указывает на вершину стека. Как и в случае стопки тарелок, вершина стека это то место, в котором в стеке сохраняется следующее помещенное туда значение. Действие, состоящее в занесении значений в стек, называют также «заталкиванием» (pushing) в стек. В самом деле, инструкция PUSH используется для занесения значений в стек. Аналогично, действие, состоящее в извлечении (выборке) значений из стека, называют также «выталкиванием» (popping) из стека (для этого используется инструкция POP).

На Рис. 4.6 показывается, как изменяются регистры SP, AX и BP по мере выполнения следующего кода (при этом подразумевается, что начальное значение SP равно 1000):

mov ax,1

push ax

mov bx,2

push bx

pop ax

pop bx

Вначале: | |

||

AX | ? | 996 | ? |

| |

||

BX | ? | 998 | ? |

| |

||

SP | 1000 |> 1000 | ? |

| |

||

После mov ax,1 / push ax: | |

||

AX | 1 | 996 | ? |

| |

||

BX | ? | > 998 | 1 |

| | |

| ||

SP | 998 | 1000 | ? |

| |

||

После mov bx,2 / push bx: | |

||

AX | 1 | > 996 | 2 |

| | |

| ||

BX | 2 | | 998 | 1 |

| | |

| ||

SP | 996 | 1000 | ? |

| |

||

После pop ax: | |

||

AX | 2 | 996 | ? |

| |

||

BX | 2 | > 998 | 1 |

| | |

| ||

SP | 998 | 1000 | ? |

| |

||

После pop bx: | |

||

AX | 2 | 996 | ? |

| |

||

BX | 1 | 998 | 1 |

| |

||

SP | 1000 |> 1000 | ? |

| |

||

Рис. 4.6 Регистры AX, BX, SP и стек.

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

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

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

Загрузка...