Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados...

Preview:

Citation preview

Linguagem de Montagem

Correção Exercício

extern printf, scanf

segment .data

//dados inicializados

segment .bbs

/dados não inicializados

segment .text

//programa principal

extern printf, scanfsegment .data//dados inicializadossegment .bbs/dados não inicializadossegment .text

global mainmain:

enter 0,0// ...leaveret

Exercício

• Escrever um procedimento chamado locate, este deve localizar um caractere em uma dada string.

• O procedimento recebe como parâmetro o caractere a ser localizado, a string e a primeira posição em que começa a busca.

Exercício

• Quando o caractere é encontrado é retornado a posição deste na string, se tal caractere não for encontrado deverá ser retornado um valor negativo.

• O programa principal deverá chamar o procedimento e informar todas as posições que o dado caractere ocorre na palavra, caso não ocorra nenhuma vez ele deve exibir uma mensagem.

extern printf, scanf

segment .data

string db “Isto eh uma strig”,0

letra db “s”

formato db “%d”

msg db “letra não encontrada”,0

segment .text

global main

main:

enter 0,0

// ...

leave

ret

extern printf, scanfsegment .data string db “Isto eh uma strig”,0

letra db “s”formato db “%d”msg db “letra não encontrada”,0

segment .textglobal mainmain:

enter 0,0;EBX contém primeiro endereçomov EBX, string;AL contém letramov AL,[letra];chamar procedimento com os parâmetroscall locate

leaveret

segment .textglobal mainmain: enter 0,0 ;EBX contém 1o. endereço mov EBX, string ;AL contém letra mov AL,[letra] ;chamar procedimento call locate leaveret

locate: ;EBX contém endereço da string ;AL contém caractere ;AH contém posição

repeat : cmp byte [EBX],AL

je achou inc AH inc EBX cmp byte [EBX],0 jne repeat achou: ret

Exercício

• Até agora acha a primeira letra.

• Escrever um procedimento chamado locate, este deve localizar um caractere em uma dada string.

• O procedimento recebe como parâmetro o caractere a ser localizado, a string e a primeira posição em que começa a busca.

Exercício

• Quando o caractere é encontrado é retornado a posição deste na string, se tal caractere não for encontrado deverá ser retornado um valor negativo.

• O programa principal deverá chamar o procedimento e informar todas as posições que o dado caractere ocorre na palavra, caso não ocorra nenhuma vez ele deve exibir uma mensagem.

segment .textglobal mainmain: enter 0,0 ;EBX contém 1o. endereço mov EBX, string ;AL contém letra mov AL,[letra] ;chamar procedimento call locate leaveret

locate: ;EBX contém endereço da string ;AL contém caractere ;AH contém posição

repeat : cmp byte [EBX],AL

je achou inc AH inc EBX cmp byte [EBX],0 jne repeat achou: ret

Exercício

• Quando o caractere é encontrado é retornado a posição deste na string, se tal caractere não for encontrado deverá ser retornado um valor negativo.

• O programa principal deverá chamar o procedimento e informar todas as posições que o dado caractere ocorre na palavra, caso não ocorra nenhuma vez ele deve exibir uma mensagem.

segment .text

global main

main:

enter 0,0

;EBX contém 1o. endereço

mov EBX, string

;AL contém letra

mov AL,[letra]

;chamar procedimento

call locate

push EBX

push ECX

push EAX

;escreve posição push AH push dword formato call printf add esp, 5 pop EAX pop ECX pop EBXleaveret

locate:

segment .textglobal mainmain: enter 0,0 mov EBX, string mov AL,[letra]

proximo: call locate push EBX push ECX push EAX ;escreve posição push AH push dword formato call printf add esp, 5

pop EAX pop ECX pop EBX

cmp byte [EBX],0 je fim

inc EBX inc AH jmp proximo fim:

leaveret

locate: ...

Conteúdo

• Passagem de Parâmetros– Método da Pilha

• Anteriormente: – Método do Registrador

• Prova dia 03/12

Pilha e Procedimento

• Procedimentos são mecanismos que facilitam a programação modular.

• As pilhas desempenham um papel importante na chamada e execução de procedimentos.

• Uma pilha é uma entrada de dados do tipo LIFO.

• PUSH e POP

Registradores

• EIP (Instruction Pointer)– aponta para próxima instrução, possui o

valor de deslocamento (offset) do código da próxima instrução a ser executada.

Implementação da Pilha

• O espaço de memória reservado no segmento de pilha é utilizado para implementar a pilha.

• Os registradores SS e ESP são utilizados para implementar uma pilha no Pentium.

• O topo da pilha que aponta para o último item inserido que é indicado por SS:ESP

Sobre pilha

• O registrador de segmento SS – utilizado para identificar a área de memória

que será usada como pilha.– Aponta para o inicio do segmento da pilha

• ESP – fornece o endereço offset do último item

inserido.

• TOS = topo da pilha

Implementação Pentium

• Apenas words (16-bits) ou doublewords (32-bits) são salvos na pilha, nunca um único byte

• A pilha cresce em direção ao endereço de memória mais baixo.

• TOS aponta para o último item colocado na pilha, aponta para o byte mais baixo da última word inserida.

•Pilha vazia com 256 bytes de memória reservados para realizar operações na pilha.

•Quando a pilha é inicializada, TOS aponta para o byte seguinte a area reservada para a pilha. •Ler de uma pilha vazia causa o erro que chamamos de stack underflow.

Quando uma word é colocada na pilha, ESP é decrementado de 2, e a word é armazenada em SS:ESP.

Como o Pentium usa a ordenação de bytes little-endian, o byte de ordem mais alta é armazenado no endereço mais alto.

Funcionamento da Pilha

• A condição de pilha cheia é indicada pelo valor offset igual a 0 (ESP = 0).

• Se tentarmos inserir um item em uma pilha cheia ocorre stack overflow.

• Recuperar um dado de 32-bits da pilha causa um aumento de 4 no valor offset, este apontando então para o próximo item da pilha.

• A memória retém seus valores. • TOS é atualizado

Método da Pilha

• Neste método todos os parâmetros são colocados na pilha antes do procedimento ser chamado.

push [number1]

push [number2]

call sum

Método da Pilha

n1

n2

Endereço de retorno (EIP)

TOSSP

push n1push n2call sum

Após executar a instrução call, que automaticamente coloca o conteúdo de EIP na pilha temos uma pilha como mostrada na figura ao lado.

Método da Pilha

n1

n2

Endereço de retorno

TOSSP

Os valores de n1 e n2 estão enterrados dentro da pilha

Devemos retirar o valor de EIP antes de ler os dois valores passados.

pop EAXpop EBXpop ECX

Como removemos o endereço de retorno (EIP) da pilha, devemos colocá-lo de volta utilizando para isso um push EAX.

Método da Pilha

• Problema deste código:– Usa registradores para copiar os valores dos

parâmetros, o que significa que o procedimento não poderá utilizar estes registradores para nenhum outro propósito.

• Solução – Copiar os parâmetros da pilha para variáveis

locais, mas isso é totalmente ineficiente.

Método da Pilha

n1

n2

Endereço de retorno ESP

ESP+4

ESP+6

• A melhor forma de pegar os parâmetros é deixá-los na pilha e lê-los diretamente da pilha quando necessário.

• A pilha é uma seqüência de espaços na memória.

Método da Pilha

n1

n2

Endereço de retorno ESP

ESP+4

ESP+6

MOV EBX,[ESP+4] pode ser usado para ler n2

Problema: O ponteiro da pilha é atualizado através das operações push e pop, como resultado, o offset relativo muda com as operações na pilha feitas pelo procedimento chamado.

Método da Pilha

n1

n2

Endereço de retorno EBP

ESP

Solução:Usar o registrador EBP ao invés de ESP para especificar o offset dentro do segmento da pilha.

mov EBP,ESPmov AX,[EBP+4]

EBP+4

EBP+8

Método da Pilha

• Esta é a forma usual de se acessar parâmetros da pilha.

• Já que todo procedimento usa o registrador EBP para acessar os parâmetros, o registrador EBP deverá ser preservado. – Devemos salvar o conteúdo do registrador EBP,

antes de fazermos o MOV, usando a pilha para isto. – Note que mov EBP,ESP faz com que o parâmetro de

deslocamento aumente de quatro bytes

Método da Pilha

n1

n2

Endereço de retorno

EBP EBPESP

push EBPmov EBP,ESPmov AX,[EBP+8]

EBP+4

EBP+8

EBP+10

Método da Pilha

• stack frame(moldura da pilha) = informação armazenada na pilha– parâmetros, – endereço de retorno, – valor antigo de EBP

• A stack frame também consiste de variáveis locais caso o procedimento as use.

Método da Pilha

• O valor EBP é referenciado como frame pointer(FP).

• Uma vez que o valor de EBP é conhecido, podemos acessar todos os itens na moldura da pilha.

• Antes de retornar do procedimento devemos lembrar de fazer um pop EBP para restaurar o valor original de EBP.

• A instrução ret faz com que o endereço de retorno seja armazenado no registrador EIP.

Método da Pilha

• Os quatro bytes da pilha ocupados pelos dois parâmetros não tem mais uso.

• Uma forma de liberar estes quatro bytes é incrementar ESP em quatro após a instrução call.

push number1push number2call sumadd ESP,4

Passagem de Parâmetro pela Pilha; Entrada: Dois inteiros dado pelo usuário.; Saída: Soma dos dois inteiros, colocado em AX.segment .bbs n1 resw 1

n2 resw 1

segment .text;ler n1 e n2

mov CX,[n1] mov DX, [n2] push CX ; coloca primeiro número na pilha push DX ; coloca segundo número na pilha call sum ; retorna soma em AX

; escreve resultado em AX

Passagem de Parâmetro pela Pilha

segment .text;ler n1 e n2

mov CX,[n1] mov DX, n2 push CX

push DX

call sum

CX/n1

DX/n2

Endereço de retorno

EBPESP

EBP+4

EBP+8

Passagem de Parâmetro pela Pilha

;------------------------------------------------;Recebe dois inteiros via pilha.;O resultado é retornado em AX.;------------------------------------------------sum:

push EBP ; salva EBP mov EBP, ESP

mov AX,[EBP+10] ; sum = n1add AX,[EBP+8] ; sum = sum + n2

pop EBP ; restaura EBPret ; retorna

CX/n1

DX/n2

Endereço de retorno

EBP EBPESP

EBP+4

EBP+8

EBP+10

Passagem de Parâmetro pela Pilha; Entrada: Dois inteiros dado pelo usuário.; Saída: Soma dos dois inteiros, colocado em AX.segment .bbs n1 resw 1

n2 resw 1

segment .text;ler n1 e n2

mov CX,[n1] mov DX, n2 push CX ; coloca primeiro número na pilha push DX ; coloca segundo número na pilha call sum ; retorna soma em AX add ESP,4

; escreve resultado em AX

Exercício

• Escreva um procedimento chamado MAX que receba três inteiros do programa principal e retorne o máximo dos três em AX. O programa principal deve pedir ao usuário que entre os três inteiros e mostrar na tela o maior deles utilizando para isso o procedimento MAX.

Recommended