A Aldeia Numaboa ancestral ainda está disponível para visitação. É a versão mais antiga da Aldeia que eu não quis simplesmente descartar depois de mais de 10 milhões de pageviews. Como diz a Sirley, nossa cozinheira e filósofa de plantão: "Misericórdia, ai que dó!"

Se você tiver curiosidade, o endereço é numaboa.net.br.

Leia mais...

Oficina

3. Curso relâmpago de Assembly

Sex

25

Mai

2007


20:08

(54 votos, média 4.63 de 5) 


A Pilha

A pilha é uma área especial de memória dentro do processador. Informações guardadas na pilha com PUSH são colocadas no topo. Quando informações são tiradas da pilha com POP, estas também são tiradas do topo. Isto resulta numa regra simples: os últimos dados que entram na pilha são os primeiros a sair. A pilha é muito utilizada pelas rotinas dos códigos operacionais do computador. Por exemplo, toda instrução CALL põe o endereço da instrução de chamada na pilha para que a instrução de retorno RETN saiba para onde saltar para voltar ao ponto de chamada.

Veja um pouco de código usando PUSH e POP e observe como os valores dos registradores AX e BX foram trocados com o auxílio da pilha:

mov ax, 123 mov bx, 456 push ax ; Topo da pilha = 123 push bx ; Topo da pilha = 456 pop ax ; AX = Topo da pilha = 456 pop bx ; BX = Topo da pilha = 123

Segmentos e Deslocamentos

Este é o tipo de assunto que no início dá nó na cabeça de qualquer um, mas, uma vez entendido, facilita muito a programação Assembly.

Segmentos

Quando as máquinas foram melhoradas, a memória do computador (aquelas "tripinhas" de chips que a gente espeta na placa-mãe) passou a armazenar vários megabytes - muitas vezes o maior número que conseguimos obter com 16 bits. Num sistema de 16 bits, o maior número que conseguimos obter é 1111 1111 1111 1111 em binário ou 65535 em decimal. Este número corresponde a 64 Kb, muito longe dos megabytes. A questão era: o que fazer para acessar posições de memória acima de 65535?

Foi daí que o pessoal resolveu "lotear" a memória em segmentos e, adivinhe, cada segmento com 65536 bytes (de 0 a 65535). Para acessar qualquer ponto da memória, passou-se a usar um duplo endereço: o número do segmento e a posição dentro deste segmento. Com os segmentos colocados um após o outro, as posições de memória ficariam da seguinte forma:

  • Segmento 0 começa na posição 0 e vai até 65535
  • Segmento 1 começa na posição 65536 e vai até 131071
  • ...

Acontece que nem sempre os dados colocados na memória, como programas, dados e a pilha, ocupavam segmentos inteiros. Como resultado, a memória - chipzinhos caros pra caramba - pareciam um queijo suiço cheio de buracos. Resolveu-se então sobrepor os segmentos usando uma distância entre eles de 16 bytes. Desta forma, as posições de memória foram loteadas assim:

   Segmento 0 começa na posição 0 e vai até 65535
   Segmento 1 começa na posição 16 e vai até 65551
   ...
   Segmento 100 começa na posição 1600 e vai até 67135
   ...
   Segmento X começa na posição X*16 e vai até X*16 + 65535

Deslocamento

O deslocamento (offset) é um endereço relativo porque depende do segmento. Nada mais é do que a posição de determinado byte dentro das 65536 posições possíveis. Lembre-se de que as posições são numeradas de 0 a 65535, o que dá o total de 65536 posições. Lembre-se também que o deslocamento nunca pode ser maior do que 65535 porque... não conseguimos um número maior do que este com 16 bits.

O deslocamento é a segunda porção do duplo endereço de uma posição de memória, geralmente indicada por Segmento:Deslocamento. Para facilitar, vamos a um exemplo prático:

   Endereço 1234:5678 => Segmento 1234 e Deslocamento 5678
   
   Início do segmento => 1234 * 16 = 19744
   Deslocamento dentro do segmento =  5678
                                     ------
   Endereço da memória               25422

O processador possui registradores especiais para gerenciar os segmentos. Os principais são o CS (Code Segment), o DS (Data Segment) e o ES (Extra Segment). O CS gerencia os segmentos onde se encontra o código do programa, o DS gerencia os segmentos que contêm os dados do programa e o ES é um gerenciador adicional. Para o deslocamento também existe um registrador especial, o SI (Segment Index). Quando queremos acessar algum dado, é a dupla DS:SI que contém o endereço deste dado.

Se bagunçarmos estes registradores, os resultados podem ser catastróficos (nem preciso explicar porque laugh Para evitar que inadvertidamente se mude os valores destes registradores, não existem instruções que façam alterações diretas - os valores só podem ser alterados indiretamente, forçando a atenção dos programadores. Veja um exemplo:

mov ax, 1000 ; AX = 1000 mov ds, ax ; Altera o número do segmento para 1000 mov ax, [ds:0] ; Põe word do endereço 1000:0000 em AX ; - o endereço é 16000 mov [1234], ax ; Põe valor de AX no segmento atual no ; deslocamento 1234 inc ax ; Incrementa AX mov [ds:32], ax ; Põe valor de AX no endereço 1000:0032 ; - o endereço é 16032

Informações adicionais