CodeNet / Языки программирования / Ассемблер / СПРАВОЧНИК по системе программирования ТУРБО АССЕМБЛЕР 2.0
СПРАВОЧНИК по системе программирования ТУРБО АССЕМБЛЕР 2.0
Регистр 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 непосредственно. Любой из других семи регистров общего назначения можно спокойно изме- нять в любой момент. Указатель инструкций ----------------------------------------------------------------- Указатель инструкций (регистр IP) всегда содержит смещение в памяти, по которому хранится следующая выполняемая инструкция. Когда выполняется одна инструкция, указатель инструкций перемеща- ется таким образом, чтобы указывать на адрес памяти, где хранится следующая инструкция. Обычно следующей выполняемой инструкцией является инструкция, хранимая по следующему адресу памяти, но не- которые инструкции, такие, как вызовы или переходы, могут привес- ти к тому, что в указатель инструкций будет загружено новое зна- чение. Таким образом, будет выполнен переход на другой участок программы. Значение счетчика инструкций нельзя прочитать или записать непосредственно. Загрузить в указатель инструкций новое значение может только специальная инструкция перехода (аналогичная только что описанным). Указатель инструкций сам по себе не определяет адрес, по ко- торому находится следующая выполняемая инструкция. Картину здесь опять усложняет сегментная организация памяти процессора 8086. Для извлечения инструкции предусмотрен регистр CS, где хранится базовый адрес, при этом указатель инструкций задает смещение от- носительно этого базового адреса. Каждый раз, когда мы говорим об адресации памяти, нам прихо- дится упоминать сегменты. И каждый раз мы откладываем на потом полное объяснение данного вопроса. Теперь пришло время этим за- няться.
Оставить комментарий
Комментарии
1.
6 января 2011, 11:50:08
"последний-пришел-первый-ушел" (FIFO) - скорей всего опечатка.. Правильно LIFO..