Вы находитесь на странице: 1из 12

Programao Imperativa em C e C++ PICC

Assembly Arquitectura IA32

Centro de Clculo Instituto Superior de Engenharia de Lisboa

Pedro Pereira palex@cc.isel.ipl.pt

Compilao gerando assembly


cl /c /FA /Od incMod.c
incMod.C
... int v;

incMod.asm
_DATA COMM _DATA PUBLIC _TEXT _incMod mov inc mov cmp jne mov $L1: mov ret _incMod _TEXT SEGMENT _v:DWORD ENDS _incMod SEGMENT PROC eax, [_v] eax [_v], eax [_v], 10 $L1 [_v], 0

cl /c /FA /Ox incMod.c


Optimizado
_incMod mov inc cmp jne xor PROC eax, [_v] eax eax, 10 $L1 eax, eax

int incMod() { ++v; if (v==10) v=0; return v; }

eax, [_v]
ENDP ENDS

$L1: mov [_v], eax ret _incMod ENDP

CCISEL, 2007

Programao Imperativa em C e C++

Arquitectura IA32

Arquitectura Intel a 32 bits


Registos
eax

Instrues
mov, inc, cmp, jne, ret, xor

Por qu saber IA32?


Debug (demo) Optimizar cdigo (mesmo que escrito em C) Melhor compreenso do C
Ponteiros; Passagem de parmetros; etc
CCISEL, 2007 Programao Imperativa em C e C++ 3

Histria dos processadores Intel IA32


1978 8086 (8MHz)
16 bits Endereamento a 220 bytes (1MB)

(famlia x86)

1989 80486 (25MHz)


Organizao em pipeline

1992 Pentium (60MHz)


Organizao super-escalar

1980 8087
Vrgula flutuante

1995 P6 (200MHz)
Organizao com escalonamento dinmico Espao endereamento (64GB)

1982 80286 (12.5MHz)


Endereamento a 224 bytes (16MB) Segmentao

1985 80386 (20MHz)


32 bits Endereamento a 232 bytes (4GB) Paginao

1997 MMX (266MHz) 1999 Pentium III (500MHz) 2000 Pentium 4 (1.5GHz) 2006 Core 2 (3GHz)

CCISEL, 2007

Programao Imperativa em C e C++

Registos
8 registos de 32 bits de uso (quase) genrico (alguns com acesso a 8 e 16 bits)
esp ebp esi, edi ecx stack pointer base pointer (em strings) (em contagens) Instruction Pointer (para flags)
32 bit

32 bit
eax ebx ecx edx esi edi ebp esp

16 bit 8 bit ah
bh

16 bit
ax bx cx dx si di bp sp

al
bl

ch
dh si di

cl
dl

Outros registos
eip eflags

bp sp

c-carry; p-parity; z-zero; s-sign; o-overflow; d-direction

cs, ds, ss, es, fs, gs selectores de segmento (16 bits)


CCISEL, 2007 Programao Imperativa em C e C++ 5

Instrues
Instrues com 0, 1 ou 2 operandos
hlt inc ebx mov eax, [esi+16]

Com 2 operandos (o primeiro especifica o destino)


Registo, Registo Registo, Imediato Registo, Memria Memria, Registo Memria, Imediato Memria, Memria mov add cmp mov sub eax, ebx, ecx, [ebx], [esi], ecx 10 [ebx] eax 3

Instrues para: Transferncia de dados: mov, push, pop, pusha, popa, Aritmticas e lgicas: add, sub, mul, div, inc, neg, cmp, and, or, Deslocamento e rotao de bits: shr, shl, ror, rol, rcr, rcl, Transferncia de controle: jmp, call, ret, iret, int, j**, Operaes sobre strings: movs, cmps, scas, lods, stos, Controle das flags: stc, clc, std, cld, pushf, popf, ...

CCISEL, 2007

Programao Imperativa em C e C++

Formas de endereamento
Endereo dentro do segmento Forma genrica
endereo = registo + scale*registo + imediato
registo qualquer registo a 32 bits scale 1, 2, 4 ou 8 imediato definido a 8, 16 ou 32 bits

No necessita de ter todas as componentes


Endereo = imediato (directo) Endereo = registo (indirecto) Endereo = registo + imediato (baseado) Endereo = registo + registo (indexado) Endereo = registo + scale*registo (indexado escalado)

Exemplo
mov eax, [esi+4*edi+15]

CCISEL, 2007

Programao Imperativa em C e C++

stack frame
Chamada
1. Passagem de parmetros
O chamador empilha os parmetros da direita para a esquerda

esp

2. Chamada
O endereo de retorno empilhado pela instruo call

3. Acertar ebp (base pointer) e alojar as variveis locais


A funo chamada empilha o valor de ebp guarda o valor de esp em ebp reserva espao para as variveis locais ajustando o valor de esp

topo do stack Variveis locais

ebp

ebp antigo
Endereo de Retorno Parmetros
endereos menores endereos maiores

Retorno
4. Valor de retorno
A funo chamada deixa em eax o valor de retorno

5. Libertar espao das variveis locais


A funo chamada repe o valor esp e ebp

6. Retornar ao chamador
A execuo passa para o chamador pela instruo ret

7. Libertar espao dos parmetros


O chamador ajusta o esp

CCISEL, 2007

Programao Imperativa em C e C++

stack frame (2)


chamador
void func() { int x = 10; ... x = sum(x,20); ... } _func PROC ... push 20 1 mov eax, [ebp-4] push eax 2 call _sum $L1: 7 add esp, 8 mov [ebp-4], eax ... _func ENDP

chamado
int sum(int a, int b) { int res = a; esp res +=b; [ebp-4] return res; ebp } _sum push 3 mov sub mov mov add mov 4 mov mov 5 pop 6 ret _sum PROC Prlogo ebp ebp, esp [ebp+8] esp, 4 eax, [ebp+8] [ebp+12] [ebp-4], eax eax, [ebp+12] [ebp-4], eax eax, [ebp-4] esp, ebp ebp 0 Eplogo ENDP

res = ?? ebp (func)


stack frame da funo sum()
9

$L1 a = 10
b = 20 x=0 ebp (main) ret addr

CCISEL, 2007

Programao Imperativa em C e C++

stack frame da funo func()

Convenes IA32/C na chamada de funes


Parmetros empilhados da direita para a esquerda
O primeiro parmetro fica no topo do stack para permitir nmero varivel de parmetros printf(frmt,)

Parmetros char, short, int e long so empilhados numa word (32 bits)
Tipos maiores ocupam 2 ou mais words no stack

O chamador responsvel por desempilhar os parmetros


Adicionar a esp (4*words dos parmetros)

O resultado da funo fica em eax, ax ou al conforme o tipo 32, 16 ou 8 bits Os registos tm que ser preservados pelas funes chamadas (no retorno devem ter os mesmos valores que na entrada), exceptuando eax, edx e ecx que podem ser usados livremente.
CCISEL, 2007 Programao Imperativa em C e C++ 10

Ligao entre C e Assembly (funo em assembly)


ml /c distance_ones.asm gera distance_ones.obj
.686P

distance_ones.asm
$while1: test cl, 1 jnz $while2 ; while(!(val&1)) shr ecx, 1 ; val>>=1 jmp $while1 $while2: test ecx, ecx jz $end ; while(val) inc eax ; ++c shr ecx, 1 ; val>>=1 jmp $while2 $end: ret ; return c _distance_ones ENDP _TEXT ENDS END

PUBLIC _distance_ones ;int distance_ones(unsigned val) ;{ ; int c=0; ; if( !val ) return 0; ; while(!(val&1)) val>>=1; ; while( val ) { ++c; val>>=1; } ; return c; ;} _TEXT SEGMENT _distance_ones PROC mov ecx, [esp+4] ; val --> ecx xor eax, eax ; c=0 --> eax test ecx, ecx jz $end ; if (!val)
CCISEL, 2007

Programao Imperativa em C e C++

11

Ligao entre C e Assembly (Chamada a partir de C)


cl prog.c distance_ones.obj gera prog.exe.

prog.c
#include <stdio.h> int distance_ones(unsigned v); int main() { int dist, val; scanf(%d,&val); bits = distance_ones(val) printf(dist=%d\n",dist); return 0; }

CCISEL, 2007

Programao Imperativa em C e C++

12

Вам также может понравиться