Parte 1: Organização de Computadores 7. Compilando programas Texto base: capítulo 3 Computer Organization and Design: The Hardware/Software Interface J.L. Hennessy e D.A. Patterson IC - UFF MIPS: Visão do programador Alguns registradores (32 bits) IC - UFF $s0 - $s7: uso geral, preservados $t0 - $t9: temporários, não preservados $sp: apontador de pilha, preservado $ra: endereço de retorno, preservado $a0 - $a3: argumentos, não preservados $v0 - $v1: valores de retorno, não preservados Algumas instruções Categoria Aritmética Transf. de dados IC - UFF Instrução add subtract load word store word Exemplo add $s1,$s2,$s3 sub $s1,$s2,$s3 lw $s1,100($s2) sw $s1,100($s2) Significado $s1 = $s2 + $s3 $s1 = $s2 - $s3 $s1=memo[$s2+100] memo[$s2+100]=$s1 Formato das instruções Campo op rs rt rd shamt funct Significado código da operação registro fonte do primeiro operando registro fonte do segundo operando registro destino do operando número de bits deslocados função; indica a variante do código de operação Formato tipo R op rs 6 bits 5 bits rt 5 bits Formato tipo I op rs 6 bits 5 bits rt 5 bits IC - UFF rd 5 bits shamt 5 bits endereço 16 bits funct 6 bits Um pequeno segmento em C Variáveis a e colocadas nos registradores $s1 $s5 pelo compilador Código C a = b + c; d = a – e; IC - UFF Código MIPS Um pequeno segmento em C Variáveis a e colocadas nos registradores $s1 $s5 pelo compilador IC - UFF Código C Código MIPS a = b + c; d = a – e; add $s1,$s2,$s3 sub $s4,$s1,$s5 Um pouco mais de complexidade Variáveis f j em $s0 $s4 Código C f = (g + h) – (i + j); IC - UFF Código MIPS Um pouco mais de complexidade Variáveis f j em $s0 $s4 IC - UFF Código C Código MIPS f = (g + h) – (i + j); add $t0,$s1,$s2 add $t1,$s3,$s4 sub $s0,$t0,$t1 Um operando em memória A é um array de 100 posições; g e h estão em $s1 e $s2; endereço de base de A está em $s3 Código C g = h + A[8]; IC - UFF Código MIPS Um operando em memória A é um array de 100 posições; g e h estão em $s1 e $s2; endereço de base de A está em $s3 IC - UFF Código C Código MIPS g = h + A[8]; lw $t0,32($s3) add $s1,$s2,$t0 ? Ainda outro array A é um array de 100 posições; h está em $s2; endereço de base de A está em $s3 Código C A[12] = h + A[8]; IC - UFF Código MIPS Ainda outro array A é um array de 100 posições; h está em $s2; endereço de base de A está em $s3 IC - UFF Código C Código MIPS A[12] = h + A[8]; lw $t0,32($s3) add $t0,$s2,$t0 sw $t0,48($s3) Array com índice variável A é um array de 100 posições; g, h e i estão em $s1, $s2 e $s4; endereço de base de A está em $s3 Código C g = h + A[i]; IC - UFF Código MIPS Array com índice variável A é um array de 100 posições; g, h e i estão em $s1, $s2 e $s4; endereço de base de A está em $s3 IC - UFF Código C Código MIPS g = h + A[i]; add $t1,$s4,$s4 add $t1,$t1,$t1 add $t1,$t1,$s3 lw $t0,0($t1) add $s1,$s2,$t0 Outras instruções Categoria Instrução Salto condicional beq bne Salto incond. j IC - UFF Exemplo beq $s1,$s2,L bne $s1,$s2,L j End Significado if($s1== $s2) go to L if($s1!= $s2) go to L go to End Tomando decisões i e j estão em $s3 e $s4; f, g e h estão em $s0, $s1 e $s2 Código C if (i == j) f = g + h; else f = g - h; IC - UFF Código MIPS Tomando decisões i e j estão em $s3 e $s4; f, g e h estão em $s0, $s1 e $s2 Código C if (i == j) f = g + h; else f = g - h; IC - UFF Código MIPS bne $s3,$s4,Else add $s0,$s1,$s2 j Exit Else: sub $s0,$s1,$s2 Exit: Loop e índice variável A é um array de 100 posições; g, h, i e j estão em $s1, $s2, $s3 e $s4; endereço de base de A está em $s5. Ex: Loop: g = g + A[i]; i = i + j; if (i != h) go to Loop; IC - UFF Código do exemplo do Loop Loop: add $t1, $s3, $s3 add $t1, $t1, $t1 add $t1, $t1, $s5 lw $t0, 0($t1) add $s1, $s1, $t0 add $s3, $s3, $s4 bne $s3, $s2, Loop IC - UFF Evitando o go to: while save é um array; i, j e k estão em $s3, $s4 e $s5; base de save está em $s6. Ex: while (save[i] == k) i = i + j; IC - UFF Código do exemplo com while Loop: add $t1, $s3, $s3 add $t1, $t1, $t1 add $t1, $t1, $s6 lw $t0, 0($t1) bne $t0, $s5, Exit add $s3, $s3, $s4 j Loop Exit: IC - UFF Mais algumas instruções Categoria Instrução Salto condicional slt Exemplo slt $s1,$s2,$s3 Salto incond. j $t0 IC - UFF jr Significado if($s2<$s3) $s1=1; else $s1=0 go to (Reg) E o switch? Variáveis f a k estão de $s0 a $s5; $t2 contém 4; $zero = 0 switch (k) { case 0: f = i + j; break; case 1: f = g + h; break; case 2: f = g - h; break; case 3: f = i - j; break; } IC - UFF Código para o switch L0: L1: L2: L3: Exit: slt $t3, $s5, $zero bne $t3, $zero, Exit slt $t3, $s5, $t2 beq $t3, $zero, Exit add $t1, $s5, $s5 add $t1, $t1, $t1 add $t1, $t1, $t4 lw $t0, 0($t1) jr $t0 add $s0, $s3, $s4 j Exit add $s0, $s1, $s2 j Exit sub $s0, $s1, $s2 j Exit sub $s0, $s3, $s4 # ($t0)=JumpTable[k] obs.: os endereços dos rótulos L0L3 encontram-se em quatro palavras seqüenciais começando no endereço IC - UFF indicado em $t4 Utilizando procedures Alocação de registros para passagem de parametros e valores IC - UFF $a0 - $a3: passagem de argumentos $v0 - $v1: retorno de valores $ra: endereço de retorno nova instrução: jal ProcedureAddress (salva endereço da próxima instrução em $ra) mais parametros/valores: uso da pilha Procedures: um caso simples int proc_simples (int g, int h, int i, int j) { int f; f = (g + h) – (i + j); return f; } IC - UFF Código MIPS: proc_simples proc_simples: sub $sp, $sp, 12 sw $t1, 8($sp) sw $t0, 4($sp) sw $s0, 0($sp) add $t0, $a0, $a1 add $t1, $a2, $a3 sub $s0, $t0, $t1 add $v0, $s0, $zero lw $s0, 0($sp) lw $t0, 4($sp) lw $t1, 8($sp) add $sp, $sp, 12 jr $ra IC - UFF Recursividade Cálculo de fatorial int fat (int n) { if (n < 1) return (1); else return (n * fat(n-1)); } IC - UFF Código MIPS: fatorial fat: L1: IC - UFF sub $sp, $sp, 8 sw $ra, 4($sp) sw $a0, 0($sp) slt $t0, $a0, 1 beq $t0, $zero, L1 add $v0, $zero, 1 add $sp, $sp, 8 jr $ra sub $a0, $a0, 1 jal fat lw $a0, 0($sp) lw $ra, 4($sp) addi $sp, $sp, 8 mult $v0, $a0, $v0 jr $ra # salva n # se n>=1, vá p/ L1 #n=n-1 # chama fat(n-1) # retorna n*fat(n-1) Arrays x ponteiros clear1 (int array[], int size) { int i; for (i = 0; i < size; i++) array[i] = 0; } clear2 (int *array, int size) { int *p; for (p = &array[0]; p <&array[size]; p++) *p = 0; } IC - UFF Código clear1 e clear2 move $t0, $zero loop1: add $t1, $t0, $t0 add $t1, $t1, $t1 add $t2, $a0, $t1 sw $zero, 0($t2) addi $t0, $t0, 1 slt $t3, $t0, $a1 bne $t3, $zero, loop1 IC - UFF move $t0, $a0 loop2: sw $zero, 0($t0) addi $t0, $t0, 4 add $t1, $a1, $a1 add $t1, $t1, $t1 add $t2, $a0, $t1 slt $t3, $t0, $t2 bne $t3, $zero, loop2 Um pouco mais rápido ... move $t0, $zero loop1: add $t1, $t0, $t0 add $t1, $t1, $t1 add $t2, $a0, $t1 sw $zero, 0($t2) addi $t0, $t0, 1 slt $t3, $t0, $a1 bne $t3, $zero, loop1 IC - UFF move $t0, $a0 add $t1, $a1, $a1 add $t1, $t1, $t1 add $t2, $a0, $t1 loop2: sw $zero, 0($t0) addi $t0, $t0, 4 slt $t3, $t0, $t2 bne $t3, $zero, loop2 Pseudo-instruções A linguagem de montagem pode ter instruções que não sejam implementadas em hardware: pseudo-instruções Exemplo: IC - UFF move $t0, $t1 # $t0 $t1 ( a MIPS!) add $t0, $zero, $t1 # equivalente ao move Transformando *.c em *.exe programa C programa fonte IC - UFF Transformando *.c em *.exe programa C compilador programa assembly IC - UFF Transformando *.c em *.exe programa C compilador programa assembly linguagem de máquina! montador módulo objeto IC - UFF Transformando *.c em *.exe programa C compilador programa assembly linguagem de máquina! montador módulo objeto IC - UFF routina de biblioteca Transformando *.c em *.exe programa C compilador programa assembly podemos ter vários módulos objeto e várias rotinas de biblioteca montador módulo objeto IC - UFF routina de biblioteca Transformando *.c em *.exe programa C linguagem de máquina! compilador programa assembly montador módulo executável ligador módulo objeto IC - UFF routina de biblioteca Transformando *.c em *.exe programa C memória compilador carregador programa assembly montador módulo executável ligador módulo objeto IC - UFF routina de biblioteca Olhando cada fase . . . Identificação dos arquivos: Unix: arq.c, arq.s, arq.o, a.out MS-DOS: arq.c, arq.asm, arq.obj, arq.exe Compilação IC - UFF código objeto pode ser produzido diretamente fases Montagem Transforma um programa em linguagem de montagem em um programa objeto: instruções de máquina, dados e informações para colocação das instruções em memória Tabela de símbolos: associação entre rótulos e seus endereços IC - UFF Arquivo objeto (e.g., Unix) Cabeçalho: tamanho e posição dos componentes do arquivo objeto Segmento de texto: código de máquina Segmento de dados: dados estáticos e dinâmicos Inf. de relocação: identifica instruções e palavras de dados que dependem de endereços absolutos quando programa é carregado IC - UFF Arquivo objeto (cont.) Tabela de símbolos: símbolos que não foram resolvidos (referências externas) Informação para depuração: possibilita associação entre instruções em C e instruções de máquina; facilita a leitura de estruturas de dados IC - UFF Um arquivo objeto Cabeçalho Nome Procedure A Tamanho do texto 10016 Tamanho dos dados 2016 Segmento de texto Endereço Instrução 0 lw $a0, 0($gp) 4 jal 0 ... ... Segmento de dados 0 (X) ... ... Inf. de relocação Endereço Tipo de instrução Dependência 0 lw X 4 jal B Tabela de símbolos Rótulo Endereço X B - IC - UFF Ligação Compilação separada: necessidade do ligador Ligador pega um programa objeto e produz um módulo carregável Ligação dinâmica em tempo de carregamento: incorporação de novas versões; compartilhamento de código Ligação dinâmica em tempo de execução: só aloca memória p/ o que for usado; instalação de módulos não existentes quando da programação da aplicação IC - UFF Carregamento Definição de endereçamento: carregamento absoluto carregamento relocável IC - UFF limitado: problema com modificações problema: memória virtual (swapping) carregamento dinâmico em tempo de execução Um programa na memória $sp Pilha Dados dinâmicos Dados estáticos Texto $pc IC - UFF PCB Leitura suplementar Apêndice A, itens A1 até A6, Computer Organization and Design: The Hardware/Software Interface, J.L. Hennessy e D.A. Patterson Apêndice 7A, Operating Systems: Internals and Design Principles, W. Stallings IC - UFF