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: 1521310 = 111011011011012 ● 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) – ● Little Endian (computadores Alpha, PCs) – ● byte menos significativo com maior endereço 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) ● ● OU (OR) ● ● A | B = 1 quando A=1 ou B=1 Negação (NOT) ● ● A & B = 1 quando A=1 e B=1 ~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 – ● ● X*2K X >> K – → deslocamento para esquerda X/2k Exemplos → deslocamento para direita 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 ● Constantes não precedidas pelo ‘$’, hexadecimais com ‘h’ no final 100h ● $0x100 Tamanho do operando indicado por operando ou sufixo de instrução sub ● movl Src, Dest 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 2 6 7 10 11 → CF: carry flag: indica a presença de um carry out; → PF: parity flag: indica se o número é ímpar; → ZF: zero flag: indica se o resultado da operação foi zero; → SF: sign flag: indica se o sinal é negativo; → DF: direction flag; → OF: overflow flag: indica se ocorreu overflow; Exercício Fazer um programa que converta inteiros para binários utilizando operações bit a bit