Pilhas

Uma pilha ocupa uma área da memória principal e armazena informações de uso geral para simplificar a execução de operações (especialmente expressões aritméticas), e também informações do salvamento de contexto, isto é, os dados presentes nos registradores ao se atender uma interrupção, executar uma chamada de sistema, enfim, a qualquer troca de contexto. No primeiro caso, a pilha torna-se disponível para o usuário e é necessário haver instruções adequadas para manipulá-las. No segundo caso, a pilha é manipulada apenas pela CPU. A maioria das CPUs trabalham com pilhas, estas podem ocupar áreas pré-determinadas, ou serem definidas pelo usuário, conforme a arquitetura.

As pilhas, na prática, constituem uma lista LIFO (Last In First Out). Imagine-se empilhando uma série de livros. Você os coloca um sobre os outros e só consegue retirar o último que colocou na pilha. Assim, para retirar o primeiro livro colocado na pilha deve-se retirar todos os que foram colocados depois. A forma de operação mais comum das pilhas é a binária, onde os dois elementos do topo da pilha são retirados e operados, sendo os dois substituídos por apenas um, correspondente ao resultado. Assim, a pilha sempre diminui de um elemento após a realização de uma operação. Há também as operações unárias, onde apenas o elemento do topo é afetado.

Os comandos utilizados para manipular a pilha (operações unárias) são:

  • PUSH – adiciona um elemento ao topo da pilha;

  • POP – retira o elemento do topo da pilha.

As operações binárias geralmente são representadas pelos mnemônicos das operações porém sem a indicação de nenhum operando. Por exemplo: ADD, SUB ou MUL tomarão os dois elementos no topo da pilha, realizarão a operação e substituirão os valores pelo resultado de forma que a pilha é reduzida em um elemento a cada operação.

Os limites da pilha e o endereço do topo da pilha precisam ser controlados. Isto é feito através dos registrados de base da pilha, limite da pilha e apontador (de topo) da pilha, muito conhecido pelo nome em inglês de Stack Pointer.

A figura ao lado exibe a organização da pilha na memória principal.


Exemplo de utilização da pilha para a realização de operações aritméticas:

Para realizar a operação:

X = (3 + 8) * 5.

Teríamos um código assembly similar ao seguinte:

PUSH    5

PUSH    8
PUSH    3
ADD
MUL
POP     X

Em cuja execução a pilha se comportaria assim:

----------- tempo ------------------------->

PUSH 5     PUSH 8     PUSH 3     ADD      MUL      POP X

                                   3

          8        8      11

   5      5        5       5     55    -----------→Pilha vazia

                                       endereço/registrador armazena X = 55


Obs.: Obviamente o conteúdo da memória foi representado em decimal.


Referência principal e fonte da figura: Apêndice 9A do livro Arquitetura e Organização de Computadores – 5a Edição, de William Stallings.