ResumosMIEI

Uma coleção de resumos, para ajudar os que precisam daquele empurrão.


Project maintained by mendess Hosted on GitHub Pages — Theme by mattgraham

Assembly

Assembly é uma linguagem de programação de baixo nível (low-level). Programar e interpretar código maquina (binário) é algo bastante trabalhoso e de difícil compreensão para o ser humano. Consequentemente, foi criado o Assembly, uma vez que é uma representação muito mais inteligível das instruções que um computador executa. Além disso, a sua conversão para linguagem máquina é bastante simples devido à existência do Assembler. Esta linguagem é muitas vezes utilizada para aceder diretamente às instruções do processador, para a manipulação direta de Hardware e para corrigir problemas de performance.

Como já devem ter visto na explicação da stack, push e pop são duas instruções básicas para colocar e remover elementos da stack. Ambas são instruções em assembly que recebem um registo.

push <reg>           Coloca no topo da stack o conteúdo do registo.

pop <reg>             Remove o valor que está topo da stack e coloca-o no registo.

mov

A instrução mov copia o valor da fonte (source) para o destino. (A fonte e o destino não podem ser ambas na memória).


mov %eax, %ebx

Copia o valor do conteúdo do registo %eax para o registo %ebx. (o registo %eax não é alterado).


mov (%eax), %ebx

Copia o valor apontado pelo conteúdo de %eax para %ebx. Nesta instrução, o que estiver no registo %eax é um apontador para um local de memória. O valor apontado será um operando num dado local da memória.

Explicação mais detalhada das diversas formas de endereçamento aqui


mov %eax, (%ebx)

Copia o valor do registo %eax para o local de memória apontado por %ebx.


mov $0x10, %ebx

Guarda o valor (imediato) 0x10 ( 16 ) no registo %ebx.


mov %eax, 0x4(%ebx)

Nesta instrução é colocado o conteúdo do registo %eax no local apontado por %ebx + 4. Os parantêses no segundo operando indicam que o destino é na memória e que terá que ser feito um acesso à mesma. Assim, é extraído o conteudo do registo %ebx e é efetuado um deslocamento relativo a esse valor para determinar o local da memória destino.

leal

A instrução leal (load effective address) tem algumas semelhanças com a instrução mov. Contudo, esta quando utiliza operandos que são apontadores não determina o valor apontado por eles. Na secção interior pode-se constatar que a utilização de () na instrução mov implica acesso à memória de modo a obter o valor apontado pelo endereço. Por outro lado, na instrução leal os parênteses não implicam acesso à memória. Desta forma, é possível realizar aritmética sobre os apontadores sem ter que ir à memória e ver para o que estes apontam.


leal $0x10(%eax), %ebx

Esta instrução soma o conteúdo de %eax com 16 (decimal) e coloca esse valor no registo %ebx.

leal -4(%eax, %edx, 4), %ebx

Nestea instrução é realizada esta operação: (%eax + %edx * 4 ) - 4 e o seu resultado é colocado no registo %ebx-


Existem muitas outras intruções de Assembly que podem ser consultas no Instruction Set.

Modos de Endereçamento:

image

Pela observação da imagem podemos constatar que existem várias formas de determinar os operandos utilizados pelas instruções Assembly.

Os parênteses, salvo na instrução leal, representam acessos à memória. Supondo que (%ebx) é um dos operandos de uma dada instrução, então o valor do registo %ebx será um apontador e para calcular o operando teremos que ver para que local de memória esse endereço aponta.

Para facilitar a compreensão segue-se uma demonstração do modo como os operandos são calculados, recorrendo a uma espécie de “pseudo-código” de C e Assembly. Não se trata de um código válido em nenhuma das linguagens, tem apenas a finalidade de expôr de forma mais fácil o cálculo dos operandos.

0x4 -> valor imediato

(%eax) -> *eax

0x8(%eax) -> *(%eax + 0x8)

0x10(%eax,%ebx,4) -> *(%eax + 4 * %ebx + 0x10)