Existem 8 registos principais de 32 bits no processador (existem mais como %EIP): %EAX %EBX %ECX...

19
Existem 8 registos principais de 32 bits no processador (existem mais como %EIP): %EAX %EBX %ECX %EDX %ESI %EDI %EBP %ESP Os registos são armazenados em hardware, diretamente no processador Ou seja, são independentes da RAM Os registos servem para armazenar valores. -Se usarmos %registo estamos a aceder diretamente ao valor desse registo. -Se usarmos (%registo) estamos a aceder ao endereço da memória que tem o numero que esta no registo

Transcript of Existem 8 registos principais de 32 bits no processador (existem mais como %EIP): %EAX %EBX %ECX...

Page 1: Existem 8 registos principais de 32 bits no processador (existem mais como %EIP): %EAX %EBX %ECX %EDX %ESI %EDI %EBP %ESP Os registos são armazenados em.

Existem 8 registos principais de 32 bits no processador (existem mais como %EIP):

%EAX%EBX%ECX%EDX

%ESI%EDI%EBP%ESP

Os registos são armazenados em hardware, diretamente no processador

Ou seja, são independentes da RAM

Os registos servem para armazenar valores.

-Se usarmos %registo estamos a aceder diretamente ao valor desse registo.

-Se usarmos (%registo) estamos a aceder ao endereço da memória que tem o numero que esta no registo

Page 2: Existem 8 registos principais de 32 bits no processador (existem mais como %EIP): %EAX %EBX %ECX %EDX %ESI %EDI %EBP %ESP Os registos são armazenados em.

Em termos de Layman…

Se usar %ebp

Obtenho 4

Se usar (%ebp)

Obtenho o que quer que está na RAM, no endereço quatro

movl $4, %edx(%EDX = 4)

Logo podemos usar registos como apontadores ou como variáveis

Page 3: Existem 8 registos principais de 32 bits no processador (existem mais como %EIP): %EAX %EBX %ECX %EDX %ESI %EDI %EBP %ESP Os registos são armazenados em.

Existem 8 registos principais de 32 bits no processador (existem mais como %EIP):

%EAX%EBX%ECX%EDX

%ESI%EDI%EBP%ESP

Por convenção, apenas %EAX,%ECX e %EDX podem ser alterados à vontade

Todos os outros contém valores que necessitam ser conservados, podemos usá-los (exceto o %ESP), mas temos que garantir que no fim da nossa função, o seu valor é restaurado.

Page 4: Existem 8 registos principais de 32 bits no processador (existem mais como %EIP): %EAX %EBX %ECX %EDX %ESI %EDI %EBP %ESP Os registos são armazenados em.

Existem 8 registos principais de 32 bits no processador (existem mais como %EIP):

%EAX%EBX%ECX%EDX

%ESI%EDI%EBP%ESP

Estas são as convenções usadas mais ou menos por quase todas as funções, podem faltar aqui algumas (mais coisa menos coisa…)

Aponta para o último elemento empilhado

Serve de referência aos argumentos de uma função (ou parametros…)

Retorno dos 4 bytes menos significativos

Retorno dos 4 bytes mais significativos

Page 5: Existem 8 registos principais de 32 bits no processador (existem mais como %EIP): %EAX %EBX %ECX %EDX %ESI %EDI %EBP %ESP Os registos são armazenados em.

Existem 8 registos principais de 32 bits no processador (existem mais como %EIP):

%EAX%EBX%ECX%EDX

%ESI%EDI%EBP%ESP

Estas são as convenções usadas mais ou menos por quase todas as funções, podem faltar aqui algumas (mais coisa menos coisa…)

Normalmente usado como o índice destino para manipulação de

vetores de chars (Strings)

Normalmente usado como o índice fonte para manipulação de vetores

de chars (Strings)

Normalmente usado como pointer para o início de uma array

Normalmente usado como counter em iterações, loops, etc

Page 6: Existem 8 registos principais de 32 bits no processador (existem mais como %EIP): %EAX %EBX %ECX %EDX %ESI %EDI %EBP %ESP Os registos são armazenados em.

Em termos de Layman…

%EAX%EBX%ECX%EDX

%ESI%EDI%EBP%ESP

AcummulatorBaseCounterSupporting register for 64 bit instructions (aka coisas maiores que 4 bytes)

Source IndexDestination IndexBase PointerStack Pointer

Page 7: Existem 8 registos principais de 32 bits no processador (existem mais como %EIP): %EAX %EBX %ECX %EDX %ESI %EDI %EBP %ESP Os registos são armazenados em.

Implementação da Função Soma Em Assembly

Page 8: Existem 8 registos principais de 32 bits no processador (existem mais como %EIP): %EAX %EBX %ECX %EDX %ESI %EDI %EBP %ESP Os registos são armazenados em.

y

x

RETURN

LIXO

C:int soma( int x, int y);

…Endereço Mais Alto

Endereço Mais Baixo

%esp

%ebp

O %ESP aponta sempre para o último elemento empilhado

Contudo, como já vimos, por convenção, o %EBP tem um valor qualquer.É necessário conservar esse valor antigo antes de o mudarmos…

Page 9: Existem 8 registos principais de 32 bits no processador (existem mais como %EIP): %EAX %EBX %ECX %EDX %ESI %EDI %EBP %ESP Os registos são armazenados em.

y

x

RETURN

LIXO

Valor de EBP

C:int soma( int x, int y);

Assembly:pushl %ebp …

Endereço Mais Alto

Endereço Mais Baixo

%esp

%ebp

Portanto primeiro empilhamos ebp para guardar na pilha o seu valor.

Page 10: Existem 8 registos principais de 32 bits no processador (existem mais como %EIP): %EAX %EBX %ECX %EDX %ESI %EDI %EBP %ESP Os registos são armazenados em.

y

x

RETURN

LIXO

C:int soma( int x, int y);

Assembly:pushl %ebp …

Endereço Mais Alto

Endereço Mais Baixo

%esp

%ebp

O ebp continua a apontar sabe-se lá para onde, mas nós queremos que ele aponte para os argumentos

Valor de EBP

Page 11: Existem 8 registos principais de 32 bits no processador (existem mais como %EIP): %EAX %EBX %ECX %EDX %ESI %EDI %EBP %ESP Os registos são armazenados em.

y

x

RETURN

LIXO

C:int soma( int x, int y);

Assembly:pushl %ebpmovl %esp, %ebp

…Endereço Mais Alto

Endereço Mais Baixo

%esp%ebpSe passarmos o endereço de esp para ebp, este fica a apontar para uma posição que nós conhecemos. Mesmo que façamos push e alteremos o esp o ebp ficará sempre no mesmo sítio. Além disso o ebp aponta para onde ficou o seu antigo endereço que depois iremos restaurar.

ebp +4

ebp +8

ebp +12

Valor de EBP

Page 12: Existem 8 registos principais de 32 bits no processador (existem mais como %EIP): %EAX %EBX %ECX %EDX %ESI %EDI %EBP %ESP Os registos são armazenados em.

y

x

RETURN

LIXO

C:int soma( int x, int y);

Assembly:pushl %ebpmovl %esp, %ebpmovl 12(%ebp), %eax

…Endereço Mais Alto

Endereço Mais Baixo

%esp%ebp

Queremos portanto somar x com y, contudo, não há nenhuma instrução que permita somar dois valores na pilha. É necessário mover um deles para um registo. Até agora temos à nossa disposição 3 registos que podemos usar livremente: %EAX, %ECX e %EDXComo já vimos a variável x tá 8 bytes acima do endereço para o qual %EBP aponta

ebp +4

ebp +8

ebp +12

EAX = y

Valor de EBP

Page 13: Existem 8 registos principais de 32 bits no processador (existem mais como %EIP): %EAX %EBX %ECX %EDX %ESI %EDI %EBP %ESP Os registos são armazenados em.

y

x

RETURN

LIXO

C:int soma( int x, int y);

Assembly:pushl %ebpmovl %esp, %ebpmovl 12(%ebp), %eax

…Endereço Mais Alto

Endereço Mais Baixo

%esp%ebp

Queremos mover o conteúdo na pilha com o endereço de %ebp +12 para um registo qualquer, por exemplo %EDX

ebp +4

ebp +8

ebp +12

EAX = y

Valor de EBP

Page 14: Existem 8 registos principais de 32 bits no processador (existem mais como %EIP): %EAX %EBX %ECX %EDX %ESI %EDI %EBP %ESP Os registos são armazenados em.

y

x

RETURN

LIXO

C:int soma( int x, int y);

Assembly:pushl %ebpmovl %esp, %ebpmovl 12(%ebp), %eaxaddl 8(%ebp), %eax

…Endereço Mais Alto

Endereço Mais Baixo

%esp%ebp

E agora somamos…

ebp +4

ebp +8

ebp +12

EAX = x+y

Valor de EBP

Page 15: Existem 8 registos principais de 32 bits no processador (existem mais como %EIP): %EAX %EBX %ECX %EDX %ESI %EDI %EBP %ESP Os registos são armazenados em.

y

x

RETURN

LIXO

C:int soma( int x, int y);

Assembly:pushl %ebpmovl %esp, %ebpmovl 12(%ebp), %eaxaddl 8(%ebp), %eax

…Endereço Mais Alto

Endereço Mais Baixo

%esp%ebpJá temos o valor mas não o podemos devolver já… Porquê? Porque escrevemos no %EBP e agora temos de voltar a repo-lo. Além disso necessitamos de repor todo o espaço que gastámos na pilha.

ebp +4

ebp +8

ebp +12

EAX = x+y

Valor de EBP

Page 16: Existem 8 registos principais de 32 bits no processador (existem mais como %EIP): %EAX %EBX %ECX %EDX %ESI %EDI %EBP %ESP Os registos são armazenados em.

y

x

RETURN

LIXO

C:int soma( int x, int y);

Assembly:pushl %ebpmovl %esp, %ebpmovl 12(%ebp), %eaxaddl 8(%ebp), %eaxmov %ebp, %esp

…Endereço Mais Alto

Endereço Mais Baixo

%esp%ebpPrimeiro, vamos colocar o %ESP a apontar para o %EBP.

Para quê? Bem neste caso, nada irá acontecer porque são iguais. Mas se tivéssemos feito mais push’s para alem do %EBP, o %ESP não apontaria para o mesmo que aponta %EBP, apontaria mais para baixo. Contudo convém utilizar sempre esta instrução, por convenção.

ebp +4

ebp +8

ebp +12

EAX = x+y

Valor de EBP

Page 17: Existem 8 registos principais de 32 bits no processador (existem mais como %EIP): %EAX %EBX %ECX %EDX %ESI %EDI %EBP %ESP Os registos são armazenados em.

y

x

RETURN

LIXO

C:int soma( int x, int y);

Assembly:pushl %ebpmovl %esp, %ebpmovl 12(%ebp), %eaxaddl 8(%ebp), %eaxmovl %ebp, %esppop %ebp

…Endereço Mais Alto

Endereço Mais Baixo

%esp

E agora restauramos o valor do %EBP

Relembrar que pop %registo é o mesmo quemovl (%esp), %registoaddl $4, %esp

ebp +4

ebp +8

ebp +12

EAX = x+y

%ebp

Valor de EBP

Page 18: Existem 8 registos principais de 32 bits no processador (existem mais como %EIP): %EAX %EBX %ECX %EDX %ESI %EDI %EBP %ESP Os registos são armazenados em.

y

x

RETURN

LIXO

C:int soma( int x, int y);

Assembly:pushl %ebpmovl %esp, %ebpmovl 12(%ebp), %eaxaddl 8(%ebp), %eaxmovl %ebp, %esppop %ebpret

…Endereço Mais Alto

Endereço Mais Baixo

%esp

E fazemos return da função.É importante referir que ret simplesmente indica que a função terminou (Na verdade é um pouco mais complexo, dado que volta para a main mas isso agora não interessa nada).Cabe à main buscar a variável que ela quer…

ebp +4

ebp +8

ebp +12

EAX = x+y

%ebp

Valor de EBP

Page 19: Existem 8 registos principais de 32 bits no processador (existem mais como %EIP): %EAX %EBX %ECX %EDX %ESI %EDI %EBP %ESP Os registos são armazenados em.

E que variável é essa?Por convenção, o registo que a main vai buscar é:-Se a função for uma void a main não lê nada

-Se a função fizer return de 4 bytes ou menos a main vai buscar o que está no %EAX (exemplo: long ints (32bits), chars, pointers (a maioria, contudo alguns podem ser maiores)

-Se a função fizer return de 8 bytes, os dados são divididos em dois registos: no %EDX ficará os números mais significativos e no %EAX os menos significativos.

Neste caso, a função é do tipo int32, logo o valor é depositado no %EAX