Linguagem de Montagem Assembly
Especificações O programa em Assembly Fica sobre a camada do Sistema Operacional Efetua chamadas ao Sistema Operacional O montador Chama-se Assembler Traduz a linguagem de montagem para a linguagem da máquina
Compilando um programa... /* oimundo.c */ #include <stdio.h> int main() { printf ( Olá Mundo!\n ); }
Passos da compilação
Arquitetura de uma máquina
CPU Unidade Central de Processamento Unidade de Controle Unidade Aritmética e Lógica Conjunto de registradores Funcionam como uma memória de acesso extremamente rápido dado Não dependem da memória principal (acesso requer sem barramento) Instruções de transferência de dados transferem dados entre memória e registradores Os operandos de diversas instruções geralmente devem estar em registradores Exemplos de registradores PC (program counter): contém o endereço da próxima instrução a ser executada Instruction register: onde é copiada cada instrução a ser executada
Barramentos e Dispositivos de E/S Barramentos: conduítes elétricos que carregam a informação entre os vários componentes da máquina Projetados para transportar palavras Dispositivos de E/S: Conexão da máquina com o mundo externo Conectados ao barramento de E/S por controladores (chipsets no próprio dispositivo ou na placa mãe) ou adaptadores (quando placa separada).
Hierarquia de memória
Execução de um programa
Representação de Dados
Representação Binária Exemplo: 15213 10 = 11101101101101 2 Vantagens: Implementação eletrônica Possibilidade de armazenar elementos com dois estados Transmissão eletrônica confiável (robustez a ruídos) Implementação eficiente de operações aritméticas
Bases Numéricas Hexadecimal Decimal Binário 0 0 0000 1 1 0001 2 2 0010 3 3 0011 4 4 0100 5 5 0101 6 6 0110 7 7 0111 8 8 1000 9 9 1001 A 10 1010 B 11 1011 C 12 1100 D 13 1101 E 14 1110 F 15 1111
Palavra (WORD) Cada máquina tem seu tamanho de palavra: número de bits ocupados por um valor inteiro número de bits de endereços A maioria das atuais máquinas tem palavra de 32 bits (4 bytes) Diferentes tipos de dados (p.ex. char, double) podem ocupar uma fração ou múltiplo do tamanho da palavra, mas sempre um número inteiro de bytes
Tamanho dos Tipos em C Tamanho em bytes dos tipos em C Int 4 bytes long int 8 bytes Char 1 byte Short 2 bytes Float 4 bytes Double 8 bytes long double 8 bytes Ponteiro 8 bytes Obs.: sizeof( Tipo ) retorna o tamanho do Tipo
Memória Orientada à Palavras Memória é um vetor de bytes (cada um com um endereço) mas o acesso ocorre palavra a palavra Endereço corresponde ao primeiro byte da palavra Endereços de palavras subsequentes diferem de 4 em máquina de 32 bits
Ordenação de Bytes Como organizar os bytes de uma palavra (4 bytes)? Big Endian (computadores Sun, Mac) byte menos significativo com maior endereço Little Endian (computadores Alpha, PCs) Byte menos significativo no menor endereço Exemplo variável x tem valor 0x01234567 (hexa) Endereço &x é 0x100
Ordenação de Bytes Transparente para o programador C Relevante quando analisamos o código de máquina Exemplo (litte endian): 01 05 64 94 04 08 add 0x8049464 Importante também para a transmissão de dados entre máquinas big e little endian
Verificação Big ou Little? #include <stdio.h> typedef unsigned char *byte_ptr; void mostra (byte_ptr inicio, int tam) { int i; for (i=0;i<tam;i++) printf("%.2x", inicio[i]); printf("\n"); } void mostra_int (int num) { mostra((byte_ptr) &num, sizeof(int)); }
Caracteres Usa-se uma tabela para mapear inteiros (não negativos) em símbolos Tabelas mais comuns: ASCII codificação em 8 bits UNICODE codificação em 16 bits Em C, tipo char define apenas 1 byte Pode-se manipular um char como um int Exemplo: if (c > 0 ) val = c 0 ;
Operadores bit a bit Podem ser aplicados a qualquer tipo C Baseados na Álgebra Booleana E (AND) A & B = 1 quando A=1 e B=1 OU (OR) A B = 1 quando A=1 ou B=1 Negação (NOT) ~A = 1 quando A = 0 Ou exclusivo (XOR) A ^ B = 1 quando A=1 e B=0 ou A=0 e B=1
Exemplos Swap sem terceira variável
Exercícios Para x=0x66 e y=0x93, faça x & y x y ~x ~y x &!y x && y x y!x!y x && ~y
Deslocamento de Bits X << K deslocamento para esquerda X * 2 K X >> K deslocamento para direita X / 2 k Exemplos
Representação de Arrays Alocação contígua na memória Primeiro elemento (a[0]) corresponde ao menor endereço de memória Tipo a[tam] ocupa sizeof(tipo)*tam bytes O nome do array equivale a um ponteiro (cujo valor não pode ser alterado) Exemplo: int a[tam], a é ponteiro constante tipo int *, e seu valor é &a[0] Nomes de arrays passados como parâmetros são endereços (do array)
Aritmética básica de ponteiros Ponteiro é um endereço para um tipo específico de dado. Ex int *, char *,... Em Tipo *pa *pa significa objeto Tipo apontado por pa. pa significa (endereço de objeto). Expressão (pa +i) = pa + sizeof(t)*i O que significam: pa++, ++pa, (*p)++? Comparação entre ponteiros (p == q, p >q ) só se são para o mesmo tipo Subtração entre dois ponteiros, (p1 p2), indica o número de elementos entre p1 e p2 Existe equivalência entre arrays e ponteiros
Exemplos
Alocação de Arrays
Arrays Aninhados Declaração vetor a[4] equivalente a int a[4][5] Variável a denota array de 4 elementos Alocados continuamente Cada elemento é um vetor de 5 int s Alocados continuamente Ordenação é por linha da matriz (elementos do vetor mais externo)
Estruturas Heterogêneas O alinhamento de structs na memória segue as regras: Os campos são alocados na ordem em que aparecem na declaração; Cada campo do struct que corresponde a uma palavra (ou múltiplas palavras) deve ser alocado em um endereço múltiplo de 4; shorts em múltiplos de 2 O início de cada estrutura tem que estar sempre alinhado em endereços múltiplos de 4
Exemplo de alinhamento
Números Negativos Complemento de 2 000, 001, 010, 011, 100, 101, 110, 111 Overflow 010 + 011
Representação de Números Negativos e Overflow
Programando em Assembly Precisa-se saber como interpretar e gerenciar a memória e como usar instruções de baixo nível para o processamento Não existem tipos e variáveis (apenas bytes na memória) Não tem-se o auxílio da verificação de tipos do compilador, que ajudam a detectar vários erros Código assembly é altamente dependente da máquina perde-se a portabilidade de uma linguagem de alto nível
Diferenças entre Assemblers Diferenças Intel/Microsoft X GAS Operandos em ordem contrária mov Dest, Src movl Src, Dest Constantes não precedidas pelo $, hexadecimais com h no final 100h $0x100 Tamanho do operando indicado por operando ou sufixo de instrução sub subl entre outros
Visão do Programador Assembly
Características do Assembly Tipos de dados básicos Inteiro de 1, 2, ou 4 bytes Valores int, short, long int, char Endereços (ponteiro sem tipo) Não existem tipos de dados complexos como arrays ou structs Apenas bytes alocados de forma contígua na memória Operações primitivas Funções aritméticas sobre registradores ou dados na memória Transferência de dados (mov) entre memória e registradores Carregar dado de memória para registrador Armazenar dado em registrador para memória Controle de fluxo de execução Desvios (jump) incondicionais Desvios condicionais (dependendo de um bit em EFLAGS)
Tipos de Dados em Assembly
Registradores São usados para armazenamento temporário de dados e endereços da memória Ex:
Principais Registradores Registradores de Dados ou de Uso Geral EAX, EBX, ECX, EDX Todos possuem acesso menor. Ex: BX, BH, BL Registrador de Ponteiro de Pilha (stack pointer - ESP) ponteiro da pilha do sistema é modificado quando um valor é colocado (pushed) ou removido (popped) da pilha Registrador de Ponteiro Base (EBP) ponteiro base da pilha do sistema fornece qual a posição inicial que pode ser utilizada pelo programa
Registrador de Sinais (Flags) EFLAGS Seus bits são utilizados para definir algumas características do processador indicam o resultado da execução da instrução (status flags) 0 CF: carry flag: indica a presença de um carry out; 2 PF: parity flag: indica se o número é ímpar; 6 ZF: zero flag: indica se o resultado da operação foi zero; 7 SF: sign flag: indica se o sinal é negativo; 10 DF: direction flag; 11 OF: overflow flag: indica se ocorreu overflow;
Exercício Fazer um programa que converta inteiros para binários utilizando operações bit a bit