• Nenhum resultado encontrado

13- AulaIHS-C-ASM

N/A
N/A
Protected

Academic year: 2021

Share "13- AulaIHS-C-ASM"

Copied!
38
0
0

Texto

(1)

Interface Hardware-Software

(2)

Camadas de Software

Camada de SW

de baixo nível

(3)

Camada de SW de Baixo Nível

Mais dependente do HW

– Embora haja muitas partes que sejam independentes

Permite acesso controlado e gerenciamento de dispositivos

de HW

– E/S

– Escalonamento de Processo

– Inicialização de dispositivos

Código mais complexo de escrever e depurar

– Deve levar em conta detalhes de HW

– Se linguagem de programação utilizada for de baixo nível,

mais linhas de código são necessárias

(4)

Linguagens de Programação Utilizadas

Mesmo sendo código de baixo nível, não implica que o

código deve ser escrito todo em assembly

Maior parte do código é escrita em linguagens de alto nível

- Pequenas partes específicas escritas em assembly

Existem muitas bibliotecas ou rotinas que permitem

acesso baixo nível a linguagens de alto nível

– POSIX – Rotinas referentes a processos

(5)

Quando Usar Assembly?

Controle total de que partes do hardware devem ser

acessadas

– Registradores específicos

Garantir que uma rotina execute de forma mais

determinística

- Compiladores de linguagem de alto nível podem modificar a

forma de execução pretendida pelo programador

- Importante para sistemas de tempo real

Rotinas específicas que linguagens de alto nível não dão

suporte

– Ex: Partes do Boot loader

(6)

Por Que Não Usar Assembly em Todo Código ?

Baixa produtividade

– Muitas linhas de código para fazer o que poucas linhas de

código em alto nível fazem

– Depuração mais lenta e complexa

Alto custo de manutenção

Baixa portabilidade

– Códigos específicos a uma ISA

– Nem todo código de baixo nível é dependente do HW

Alternativa:

Uso conjunto de assembly e

linguagem de alto nível

(7)

Integração C-Assembly

Podemos combinar C e Assembly de diferentes formas

Módulos C e Assembly separados

– Integração através de chamadas de rotinas

– Durante a link-edição é feita a integração

Código assembly inline

(8)

Integrando Módulos C e Assembly Separados

extern imprimir SECTION .data var dq 3.5 SECTION .text global main main: push dword [var+4]

push dword [var] call imprimir add esp, 8

void imprimir(double valor){ printf(“%lf”,valor); }

Montador

Compilador

Link-editor

Teste1.asm

Teste2.c

Teste1.exe

Teste1.o

Teste2.o

(9)

Duas Formas de Integrar Módulos C e Assembly

extern imprimir SECTION .data var dq 3.5 SECTION .text global main main: push dword [var+4]

push dword [var] call imprimir add esp, 8

void imprimir(double valor){ printf(“%lf”,valor); } SECTION .text global soma soma: enter 0,0 mov eax,[ebp+8] add eax,[ebp+12] add eax,[ebp+16] leave ret #include <stdio.h>

extern int soma(int,int,int); int main() int a,b,c,value; value = soma(a,b,c); }

Assembly

chamando C

C chamando

Assembly

(10)

Chamando Rotinas Assembly em C

SECTION .text global soma soma: enter 0,0 mov eax,[ebp+8] add eax,[ebp+12] add eax,[ebp+16] leave ret #include <stdio.h>

extern int soma(int,int, int); int main() int a,b,c,value; value = soma(a,b,c); }

C chamando

Assembly

Existem convenções

para a passagem de

parâmetros do código C

para assembly e valores

de retorno

Algumas regras devem

ser seguidas no código

assembly quanto ao uso

de registradores

(11)

ESP

ESP

Passagem de Parâmetros em C

End - 16 End - 12 End - 8 End -4 End

soma(a,b,c)

ESP

ESP

ESP

a

b

c

EIP

Em C os parâmetros são

inseridos na pilha da

direita para a esquerda

(Right-pusher)

(12)

Stack Frame

Stack frame contém as

variáveis locais da

função chamada

– Stack frame cresce de

endereços maiores para

menores

– Guarda também o

começo do stack frame

da rotina que chamou a

função

Por convenção, o

registrador

EBP

guarda o

endereço do começo do

stack frame

– Conhecido como o Frame Pointer (FP)

(13)

O Que Acontece na Chamada de Rotina Assembly

SECTION .text global soma soma: enter 0,0 mov eax,[ebp+8] add eax,[ebp+12] add eax,[ebp+16] leave ret #include <stdio.h>

extern int soma(int,int,int); int main() int a=1,b=4,c=5,value; value = soma(a,b,c); }

C chamando

Assembly

mov eax,1

mov [ebp-4],eax; a=1 mov eax,4 mov [ebp-8],eax; b=4 mov eax,5 mov [ebp-12],eax; c=5 push [ebp-12] push [ebp-8] push [ebp-4] call soma add esp,12 mov [ebp-16],eax

Equivalentes

(14)

Convenção de Retorno de Funções

Funções em C utilizam determinados registradores para

retorno, portanto o código C sempre assume que as rotinas

em assembly também utilizem estes registradores

– Valores de 8,16 e 32 bits são devolvidos em

EAX

– Valores de 64 bits são devolvidos em

EDX:EAX

– Valores de ponto flutuante são devolvidos em

ST(0)

(15)

Regras de Escrita do Código Assembly

O código assembly chamado por C pode utilizar qualquer

registrador, porém deve preservar EBP,EBX,ESI e EDI

– Preservar significa colocar na pilha (salvar em memória),

antes da utilização

O assembly deve utilizar para retorno os registradores de

retorno padrão

É aconselhável começar a rotina com a instrução enter e

antes do retorno colocar a instrução leave

(16)

Instrução ENTER

Instrução para preparar um novo stack frame

Empilha EBP (ponteiro do stack frame anterior), move o valor de

ESP(topo da pilha) para EBP e aloca

bytes

para armazenar

variáveis locais (subtrai

bytes

de ESP e atualiza ESP)

nivel

informa o aninhamento da rotina, sendo 0 o maior nível

– Informa a quantidade de stack frames pointers (FPs) devem

ser copiados para o novo stack frame

– Permite o acesso de rotinas de menor nível a variáveis de

maior nível

Forma Geral

(17)

Exemplo: ENTER

enter

16

,

0

push ebp;

(1)

mov ebp,esp;

(2)

sub

esp

,16;

(3)

Equivalentes

End End - 12 End - 8 End - 4 End - 16

ESP

EBPa

ESP

EBP

ESP

EBPa = EBP antigo

(1)

(2)

(18)

Instrução LEAVE

Instrução para reverter as ações do

enter

Copia EBP para ESP para liberar espaço alocado, e então

restaura valor antigo do EBP

– Como consequencia, restaura valor antigo de ESP antes de

entrar na rotina

Forma Geral

leave

(19)

Exemplo: LEAVE

leave

mov esp,ebp;

(1)

pop

ebp

;

(2)

Equivalentes

End End - 4 End - 8 End - 12 End - 16

ESP

EBPa

ESP

EBP

ESP

EBPa = EBP antigo

(2)

(2)

EBPa

EBP

ESP

(1)

End + 4

(20)

Compilando e Linkando os Módulos

SECTION .text global soma soma: enter 0,0 mov eax,[ebp+8] add eax,[ebp+12] add eax,[ebp+16] leave ret #include <stdio.h>

extern int soma(int,int,int); int main()

int a=1,b=4,c=5,value; value = soma(a,b,c); }

Para toda rotina em um

módulo externo deve-se

utilizar a palavra extern

Para a rotina externa chamada

deve-se utilizar a palavra

global

main.c

soma.asm

Para compilar e linkar:

nasm –f elf soma.asm

(21)

Execução do Código

SECTION .text global soma soma: enter 0,0 mov eax,[ebp+8] add eax,[ebp+12] add eax,[ebp+16] leave ret #include <stdio.h>

extern int soma(int,int); int main() int a=1,b=4,c=5,value; value = soma(a,b,c); } End End - 24 End - 20 End - 16 End - 12

5

ESP

EBPa

EBP

End - 8 End - 4

(22)

Execução do Código

SECTION .text global soma soma: enter 0,0 mov eax,[ebp+8] add eax,[ebp+12] add eax,[ebp+16] leave ret #include <stdio.h>

extern int soma(int,int); int main() int a=1,b=4,c=5,value; value = soma(a,b,c); }

5

4

ESP

EBPa

EBP

End End - 24 End - 20 End - 16 End - 12 End - 8 End - 4

(23)

Execução do Código

SECTION .text global soma soma: enter 0,0 mov eax,[ebp+8] add eax,[ebp+12] add eax,[ebp+16] leave ret #include <stdio.h>

extern int soma(int,int); int main() int a=1,b=4,c=5,value; value = soma(a,b,c); }

4

1

ESP

EBPa

EBP

End End - 24 End - 20 End - 16 End - 12 End - 8 End - 4

5

(24)

Execução do Código

SECTION .text global soma soma: enter 0,0 mov eax,[ebp+8] add eax,[ebp+12] add eax,[ebp+16] leave ret #include <stdio.h>

extern int soma(int,int); int main() int a=1,b=4,c=5,value; value = soma(a,b,c); }

4

1

EIP

ESP

EBPa

EBP

End End - 24 End - 20 End - 16 End - 12 End - 8 End - 4

5

(25)

Execução do Código

SECTION .text global soma soma: enter 0,0 mov eax,[ebp+8] add eax,[ebp+12] add eax,[ebp+16] leave ret #include <stdio.h>

extern int soma(int,int); int main() int a=1,b=4,c=5,value; value = soma(a,b,c); }

4

1

EIP

EBPa

ESP,EBP

-

EAX

End End - 24 End - 20 End - 16 End - 12 End - 8 End - 4

5

(26)

Execução do Código

SECTION .text global soma soma: enter 0,0 mov eax,[ebp+8] add eax,[ebp+12] add eax,[ebp+16] leave ret #include <stdio.h>

extern int soma(int,int); int main() int a=1,b=4,c=5,value; value = soma(a,b,c); }

4

1

EIP

EBPa

ESP,EBP

1

EAX

End End - 24 End - 20 End - 16 End - 12 End - 8 End - 4

5

(27)

Execução do Código

SECTION .text global soma soma: enter 0,0 mov eax,[ebp+8] add eax,[ebp+12] add eax,[ebp+16] leave ret #include <stdio.h>

extern int soma(int,int); int main() int a=1,b=4,c=5,value; value = soma(a,b,c); }

4

1

EIP

EBPa

ESP,EBP

5

EAX

End End - 24 End - 20 End - 16 End - 12 End - 8 End - 4

5

(28)

Execução do Código

SECTION .text global soma soma: enter 0,0 mov eax,[ebp+8] add eax,[ebp+12] add eax,[ebp+16] leave ret #include <stdio.h>

extern int soma(int,int); int main() int a=1,b=4,c=5,value; value = soma(a,b,c); }

4

1

EIP

EBPa

ESP,EBP

10

EAX

End End - 24 End - 20 End - 16 End - 12 End - 8 End - 4

5

(29)

Execução do Código

SECTION .text global soma soma: enter 0,0 mov eax,[ebp+8] add eax,[ebp+12] add eax,[ebp+16] leave ret #include <stdio.h>

extern int soma(int,int); int main() int a=1,b=4,c=5,value; value = soma(a,b,c); }

4

1

EIP

EBPa

ESP

End End - 24 End - 20 End - 16 End - 12 End - 8 End - 4

5

10

EBP

EBPa

EAX

(30)

Execução do Código

SECTION .text global soma soma: enter 0,0 mov eax,[ebp+8] add eax,[ebp+12] add eax,[ebp+16] leave ret #include <stdio.h>

extern int soma(int,int,int); int main() int a=1,b=4,c=5,value; value = soma(a,b,c); }

4

1

EIP

EBPa

ESP

End End - 24 End - 20 End - 16 End - 12 End - 8 End - 4

5

10

EBP

EBPa

EAX

(31)

Outro Exemplo: Soma de Vetor

SECTION .text

global somaVetor

somaVetor: enter 0,0

mov edx,[ebp+8]; vetor mov ecx,[ebp+12]; SIZE push ebx; preservar mov ebx,0 mov eax,0 add_loop: add eax,[edx+ebx*4] inc ebx loop add_loop pop ebx leave ret #include <stdio.h> #define SIZE 4

extern int somaVetor(int*,int); int main() int vetor[]= {4,8,10,12}; int soma; soma = somaVetor(vetor,SIZE); printf(“Soma = %d”,soma); }

(32)

Chamando Funções C em Assembly

SECTION .data vetor dd 5,10,2 SIZE dd 3 SECTION .text extern min global main main: push dword [SIZE]

push dword vetor call min

add esp,8

int min(int* vetor, int size){ int i, menor = vetor[0];

for (i = 0; i<size; i++){ if (menor > vetor[i]) menor = vetor[i]; } return menor; }

Assembly

chamando C

Utilizam-se as mesmas

convenções para a

passagem de

parâmetros do código C

para assembly e valores

de retorno

(33)

ESP

ESP

Passagem de Parâmetros em C

End End - 4 End - 8 End - 12 End - 16

int min(vetor,size)

ESP

ESP

size

vetor

EIP

No código assembly

deve-se empilhar os

parâmetros da direita

para a esquerda

call min

(34)

Exemplo: Chamando a Função min e printf

SECTION .data vetor dd 5,10,2 SIZE dd 3 Msg db “min = %d",0x0a,0x00 SECTION .text extern min, printf

global main

main: push dword [SIZE]

push dword vetor call min add esp,8 push eax push dword Msg call printf add esp,8

int min(int* vetor, int size){ int i, menor = vetor[0];

for (i = 0; i<size; i++){ if (menor > vetor[i]) menor = vetor[i]; }

return menor; }

(35)

Código Assembly Inline

Podemos também inserir código assembly diretamente no

código C

Aconselhável apenas para pequenos trechos de código

– Senão o código fica bastante ilegível

Contudo, a sintaxe aceita pela maioria dos compiladores C

é a sintaxe AT&T

(36)

Algumas Diferenças da Sintaxe AT&T (1)

Para utilizar registradores, deve-se preceder o nome do

registrador com %

Os lugares dos operandos destino e fonte na instrução são

invertidos

Deve-se especificar na instrução, o tamanho dos

operandos

NASM AT&T

mov eax,ebx movl %ebx,%eax

mov dx, ax movw %ax, %dx

inc cl incb %cl

(37)

Algumas Diferenças da Sintaxe AT&T (2)

Constantes e imediatos devem ser precedidos $

Para especificar endereçamento indireto deve-se utilizar (),

em vez de []

Para utilizar endereçamento de base indexado escalar,

deve-se colocar (base,indice,escala)

NASM AT&T

mov eax,5 movl $5,%eax

add bx, word[bp] addw (%bp),%bx

(38)

Exemplo: Calculando Soma Vetor Inline

#include <stdio.h> int vetor[] = {4,8,10,12}; int soma = 0; int main() { asm("movl $vetor,%edx;" "movl $0,%ebx;" "movl $4,%ecx;" "movl $0,%eax;"

"add_loop: addl (%edx,%ebx,4),%eax;" "incl %ebx;"

"loop add_loop;" "movl %eax,soma"

);

printf("\nA soma do vetor eh = %d\n",soma); return 0;

}

Referências

Documentos relacionados

[r]

de Rodas Esp... de

Aloca durante a execução a quantidade de memória pedida (em bytes). Retorna um ponteiro genérico sobre o início do

soma: ;ao chegar aqui já guardou o RIP na pilha, -8 bytes push rbp ;salva rpb, -8 bytes ;usa-se o bp para guardar o valor de sp no stack frame ;o bp é a base para aceder os

Encontram-se previstos nos pontos II.1 e II.2 do Anexo II do Aviso. Significa que se um juiz colocado nesses lugares ou juízos for movimentado, os lugares não serão

ESP Pontuação em conhecimentos específicos C.. Pontuação em

ESP Pontuação em conhecimentos específicos C.. Pontuação em

“O _________ ___________da doença é o Trypanosoma cruzi que dentre os pertencentes ao gênero Trypanosoma é dos mais importantes, e a diversidade da formas clínicas da doença