43
Linguagem de Montagem

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

Embed Size (px)

Citation preview

Page 1: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

Linguagem de Montagem

Page 2: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

Correção Exercício

extern printf, scanf

segment .data

//dados inicializados

segment .bbs

/dados não inicializados

segment .text

//programa principal

Page 3: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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

global mainmain:

enter 0,0// ...leaveret

Page 4: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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.

Page 5: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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.

Page 6: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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

Page 7: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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

Page 8: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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

Page 9: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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.

Page 10: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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.

Page 11: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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

Page 12: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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.

Page 13: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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:

Page 14: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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: ...

Page 15: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

Conteúdo

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

• Anteriormente: – Método do Registrador

• Prova dia 03/12

Page 16: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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

Page 17: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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.

Page 18: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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

Page 19: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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

Page 20: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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.

Page 21: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

•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.

Page 22: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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.

Page 23: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa
Page 24: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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

Page 25: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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

Page 26: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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.

Page 27: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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.

Page 28: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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.

Page 29: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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.

Page 30: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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.

Page 31: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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

Page 32: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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

Page 33: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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

Page 34: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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.

Page 35: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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.

Page 36: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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

Page 37: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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

Page 38: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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

Page 39: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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

Page 40: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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

Page 41: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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

Page 42: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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

Page 43: Linguagem de Montagem. Correção Exercício extern printf, scanf segment.data //dados inicializados segment.bbs /dados não inicializados segment.text //programa

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.