IA32 Intel Architecture Capítulo 3 Slides adaptados dos slides do professor Pedro Pereira Consultar slides originais Centro de Cálculo Instituto Superior de Engenharia de Lisboa João Pedro Patriarca ([email protected]) Motivação bib: CSPP, cap. 3 • • • Debug (demo) Optimizar código (mesmo que escrito em C) Melhor compreensão do C – Ponteiros; – Passagem de parâmetros; – etc… CCISEL Programação em Sistemas Computacionais 2 Processo na geração de uma aplicação bib: CSPP, cap. 3 sum.c Pré-processador cpp , gcc –E • O pré-processador interpreta as linhas iniciadas com ‘#’ no ficheiro fonte (texto) e gera outro ficheiro fonte • O compilador gera o ficheiro em assembly (texto) com as instruções a executar • O assemblador gera o ficheiro objecto (binário) realocável com código de máquina das instruções • O Linker gera o ficheiro executável (binário) depois de juntar com o código dos outros módulos sum.i Compilador cc , gcc –S sum.s Assemblador as , gcc –c sum.o Linker ld , gcc sum gcc –Wall –pedantic –O2 –masm=intel –save-temps sum.c –o sum CCISEL Programação em Sistemas Computacionais 3 Desassemble a partir do ficheiro objecto realocável bib: CSPP, cap. 3 • Reverse do ficheiro objecto – $ objdump –d –M intel xpto.o > xpto.od • Opção d: desassembla apenas conteúdo de secções com código para o ficheiro xpto.od – $ objdump –D –M intel xpto.o > xpto.od • Opção D: desassembla conteúdo de todas as secções para ficheiro xpto.od – permite observar o conteúdo das secções de dados e constantes – $ objdump –j .data –s xpto.o • Opção –j: apresenta informação apenas da secção <name> (.data) • Opção –s: apresenta todo o conteúdo da secção referida com a opção -j CCISEL Programação em Sistemas Computacionais 4 Intruções e operandos das instruções bib: CSPP, cap. 3 • Instruções: – – – – – – Tansferência Aritméticas Lógicas Shifts Transferência de controlo Outras instruções • manipulação de bits • Instruções com 0, 1 ou 2 operandos – ret – push ebx – mov ax,cx • (o 1º operando é o destino) Tipos de operandos – Imediato (valor constante): 577 0x1F – Registo (valor em registo): eax bl ch si – Memória (valor em memória): [var_name] [esi] [edx+9] [eax+edx] CCISEL Programação em Sistemas Computacionais 5 Registos bib: CSPP, cap. 3 • • • 8 registos de 32 bits de uso (quase) genérico Alguns com acesso a 8 e 16 bits Alguns com contexto de utilização – – – – • esp ebp esi, edi ecx 32 bit stack pointer eax base pointer ebx (em strings) ecx (em contagens) edx Outros registos esi – eip Instruction Pointer edi ebp – eflags (para flags) esp • c-carry; p-parity; z-zero; s-sign; o-overflow; d-direction 32 bit 16 bit 8 bit ah bh ch dh al bl cl dl si di bp sp 16 bit ax bx cx dx si di bp sp – cs, ds, ss, es, fs, gs selectores de segmento (16 bits) 8 bits - byte 16 bits - word 32 bits - double word CCISEL Programação em Sistemas Computacionais 6 Modos de endereçamento bib: CSPP, cap. 3 • Forma genérica – endereço = [registo + scale*registo + imediato] • registo – qualquer registo a 32 bits • scale – 1, 2, 4 ou 8 • imediato – definido a 8, 16 ou 32 bits (valores positivos e negativos) • Não necessita de ter todas as componentes – – – – – • Endereço = imediato Endereço = registo Endereço = registo + imediato Endereço = registo + registo Endereço = registo + scale*registo (directo) (indirecto) (baseado) (indexado) (indexado escalado) Exemplo mov eax, [esi+4*edi+15] CCISEL Programação em Sistemas Computacionais 7 Exemplos com os modos de endereçamento bib: CSPP, cap. 3 • Dados os seguintes valores nos registos e em memória 0x100 0x1 0x3 eax ecx edx • 0x100 0xFF 0x104 0xAB 0x108 0x13 0x10C 0x11 Qual o valor que fica no registo bl com cada uma das instruções: mov bl, ah bl mov bl, [0x104] bl 0xAB bl=Mb[0x104]; mov bl, 104 bl 104 bl=104; mov bl, [eax] bl 255 bl=Mb[eax]; mov bl, [eax+4] bl 0xAB bl=Mb[eax+4]; mov bl, [eax+edx+9] bl 0x11 bl=Mb[eax+edx+9]; mov bl, [ecx*4+0xFC] bl 0xFF bl=Mb[ecx*4+0xFC]; mov bl, [eax+edx*4] bl 0x11 bl=Mb[eax+edx*4]; CCISEL 1 Programação em Sistemas Computacionais bl=ah; 8 Jumps bib: CSPP, cap. 3 • Jump incondicional – Directo: jmp .L5 goto L5; jmp L – A execução continua na instrução do endereço indicado goto eax; jmp eax – Indirecto: jmp R – A execução continua na instrução do endereço armazenado no registo indicado • Jumps condicionados aos valor das flags – – – – – – j(e|z) L js L j(g|nle) j(l|nge) j(a|nbe) j(b|nae) CCISEL if (zf) goto L; jn(e|z) L if (sf) goto L; jns L L if (~(sf^of)&~zf) j(ge|nl) L L if (sf^of) j(le|ng) L L if (~cf&~zf) j(ae|nb) L L if (cf) j(be|na) L Programação em Sistemas Computacionais if (~zf) goto L; if (~sf) … if (~(sf^of)) if ((sf^of)|zf) if (~cf) if (cf|zf) 9 Instruções com Flags bib: CSPP, cap. 3 • Comparações – cmp cmp eax, 10 A , B – Actualiza flags com o resultado de A – B sem alterar A e B test eax, eax – test A , B – Actualiza flags com o resultado de A & B sem alterar A e B • Obter valor das flags – – – – – – set(e|z) D sets D set(g|nle) set(l|nge) set(a|nbe) set(b|nae) CCISEL zf = sf = ... eax==10; eax<10; zf = sf = ... eax==0; eax<0; D – registo a 8 bits fica com 0 ou 1 D = zf; setn(e|z) D D = sf; setns D D D = ~(sf^of)&~zf; set(ge|nl) D D D = sf^of; set(le|ng) D D D = ~cf&~zf; set(ae|nb) D D D = cf; set(be|na) D Programação em Sistemas Computacionais D = ~zf; D = ~sf; D = ~(sf^of); D = (sf^of)|zf; D = ~cf; D = cf|zf; 10 Exemplo switch .text .globl test_switch2 .type test_switch2, @function test_switch2: push ebp mov eax, -1 mov ebp, esp mov edx, [ebp+16] cmp edx, 4 ja .L9 jmp [edx*4+.L8] .section .rodata .L8:.long .L3 .long .L4 .long .L5 .long .L6 .long .L7 .text .L3:mov eax, [ebp+12] add eax, [ebp+8] .L9:pop ebp ret .L7:# a+1 ret .L4:# a-b ret .L5:# a/b ret .L6:# a*b ret CCISEL bib: CSPP, cap. 3 int test_switch2(int a, int b, int op) { switch(op) { case 0: return a+b; case 1: return a-b; case 2: return a/b; case 3: return a*b; case 4: return a+1; default: return -1; } } Programação em Sistemas Computacionais 11