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”); }
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
Representação Binária
● Exemplo: 15213
10 = 111011011011012
● Vantagens:
● Implementação eletrônica
– Possibilidade de armazenar elementos com dois estados – Transmissão eletrônica confiável (robustez a ruídos)
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
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
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
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)
Exemplos
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
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
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
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
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
Números Negativos
● Complemento de 2
000, 001, 010, 011, 100, 101, 110, 111
● Overflow
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
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
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
Registradores
● São usados para armazenamento temporário
de dados e endereços da memória
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
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;
Exercício
Fazer um programa que converta inteiros para binários utilizando operações bit a bit