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:
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.