Questão usando movzbl, movswl, etc.

56 views
Skip to first unread message

Stefan Teixeira

unread,
Dec 12, 2010, 4:52:31 PM12/12/10
to Comp-Prog
Bem, é a segunda vez que foi cobrada em prova questões utilizando instruções como essas, que não aparecem em nenhuma questão de nenhuma lista de exercícios.
Sempre que eu vejo essas instruções e quando ela usa registradores tipo %al só, eu me complico demais e fico sem saber fazer...
Então, pra eu não zerar nenhuma questão dessas se for cair na PF, peço encarecidamente se alguém pode me explicar mais ou menos passo-a-passo a primeira questão da P1, que, com ela, eu tento fazer a última questão da P2, que foi no mesmo estilo.

Segue a questão em anexo pra ajudar.


Att,
Stefan Teixeira


questao1.jpg

Daniel Daim

unread,
Dec 12, 2010, 5:01:21 PM12/12/10
to comp...@googlegroups.com
Stefan,

se não me engano, esses comandos movem o valor de um registrador para outro com características especiais.

O movzbl, por exemplo, move um registrador de byte para long completando com 0.
Exemplo:
digamos, hipoteticamente, que um registrador do tipo byte guardasse 4 bits e estivesse guardando '0110'. E o registrador long guardasse 8 bits. Ao usar o comando movzbl ele faria o valor do registrador de 8 bits ser: 0000 0110 fazendo o valor do registrador byte ser preservado.

O movswl é a mesma coisa, só que ele preserva sinal, completando com 1 (se o bit mais significativo for 1) e com 0 (se o bit mais significativo for 0). Só que, nesse caso, vamos trabalhar com conversão de registrador de tipo word para long.

Basta você saber o tamanho de cada registrador para entender o que vai ficar setado após o comando.

Espero ter ajudado.

Abraço,

2010/12/12 Stefan Teixeira <stef...@gmail.com>



--
Daniel Daim L. de Araujo
Diretoria de Treinamento e Recursos Humanos

EJCM – Empresa Júnior de Consultoria em Microinformática
Departamento de Ciência da Computação – UFRJ
www.ejcm.com.br   -   (21) 2598-9440

Daniel Daim

unread,
Dec 12, 2010, 5:03:15 PM12/12/10
to comp...@googlegroups.com
Preste atenção que o comando que completa com 0 não preserva sinal, então se o número for negativo, vai passar a ser um outro número e será positivo.

2010/12/12 Daniel Daim <dan...@gmail.com>

Renan - Genééésio -

unread,
Dec 12, 2010, 5:17:02 PM12/12/10
to comp...@googlegroups.com
Só pra completar: nesse caso aí, ele tá empilhando na main 2 bytes e tá pegando como parâmetro na função f os mesmos 2 bytes, o que significa que na conversão deste código pra C, a função f recebe como parâmetro um dado do tipo short int e armazena em %ecx e um parâmetro de 4 bytes do tipo int que ele armazena em %ebx. (int = 4 bytes, short = 2 bytes)
--
Atenciosamente,
Renan Iglesias - Genésio -
http://www.dcc.ufrj.br/~genesio

Fernando Silva

unread,
Dec 12, 2010, 5:29:31 PM12/12/10
to comp...@googlegroups.com
Bem, tudo que foi falado está correto, no caso, tenta resolver a questão sabendo que:

movzXY => Move um valor de X bits para um registrador de Y bits, completando com 0s a esquerda
movsXY => Move um valor de X bits para um registrador de Y bits, completando o número repetindo o bit do sinal em todos os bits a esquerda.

Se continuar com dúvidas na questão é só falar.

Fernando Silva

unread,
Dec 12, 2010, 5:32:26 PM12/12/10
to comp...@googlegroups.com
Só para o caso de não ter ficado claro, X < Y

Stefan Teixeira

unread,
Dec 12, 2010, 5:34:16 PM12/12/10
to comp...@googlegroups.com
Beleza, obrigado pelas respostas de todo mundo. Vou ver se consigo fazer e depois posto aqui as dúvidas...

Fernando Silva

unread,
Dec 13, 2010, 4:02:15 PM12/13/10
to comp...@googlegroups.com
Como me pediram a resolução da questão, aqui vai:

Primeiro, eu tentei escrever o código assembly de uma forma um pouco mais amigavel, algo como um pseudo-código:

Função F(16bits *a, 16bits b):
    EBX = a
    ECX = (Completa com ZERO) b
    if (b < 0)
        return
    EDX = (Completa com ZERO) *a
    EAX = 0
    while (CX > AX)
        EDX = EDX - 1
        EAX = EAX + 2

    *a = DX
    return


Main:
    EBP = ESP
    ESP = ESP - 24
    [EBP - 2] = 24
    [ESP + 4] = 100
    EAX = EBP - 2
    [ESP] = EAX
    Call F
    return [EBP - 2]

Com essa estrutura, podemos ver que a Main está preperando valores para passar para a função, no caso, como os valores que entram de parametrô para a função são os 2 ao topo da pilha, foi reservado um espaço na memória, aonde se armazenou o valor inteiro 24, depois criou-se uma referência ao endereço aonde ele foi guardado, e essa referência foi empilhada, de forma a ser passada como argumento da função, por isso fica claro que o primeiro argumento é um ponteiro. O segundo argumento é só um valor inteiro, no caso o inteiro 100. Vemos também que é retornado o valor que foi usado pelo ponteiro.

OBS: não confunda o que eu estou chamando de inteiro acima, com o tipo de váriavel int.

No caso da função, acho que mesmo dessa forma, ainda fica um tanto confusa a sua função, então vamos tentar colocar em C, para avaliar corretamente:

void f(short *a, short b)
{
    short temp;

    if (b < 0)
        return;
    temp = 0;
    while (b > temp)
    {
        *a = *a - 1;
        temp = temp + 2;
    }

    return;
}

int main(void)
{
    short *x, y;
    *x = 24;
    y = 100;
    f(x, y);

    return *x
}

Bem, com o código anterior, deduzir o código C é uma tarefa mais fácil, e com o código C, dá para ver claramente o que o algoritmo faz.

Para fazer a letra b, basta rodar o algoritmo, a parte mais importante é o loop:

1) temp = 0 / *a = 24 / b = 100
2) temp = 2 / *a = 23 / b = 100
3) temp = 4 / *a = 22 / b = 100
4) temp = 6 / *a = 21 / b = 100
5) temp = 8 / *a = 20 / b = 100
6) temp = 10 / *a = 19 / b = 100
7) temp = 12 / *a = 18 / b = 100
8) temp = 14 / *a = 17 / b = 100
9) temp = 16 / *a = 16 / b = 100
10) temp = 18 / *a = 15 / b = 100
11) temp = 20 / *a = 14 / b = 100
...
temp = 100 / *a = -26 / b = 100

O valor que a main retorna é -26

Guilherme Bomfim

unread,
Dec 13, 2010, 4:38:28 PM12/13/10
to Comp-Prog
po valeu pela dica.Também estava com dúvidas

mas tomei um susto qd eu vi o algoritmo achei q fosse relativo a
questao da p2....dai pensei fuuuu
> Em 12 de dezembro de 2010 20:34, Stefan Teixeira <stefa...@gmail.com>escreveu:
>
>
>
> > Beleza, obrigado pelas respostas de todo mundo. Vou ver se consigo fazer e
> > depois posto aqui as dúvidas...
>
> > Em 12 de dezembro de 2010 20:32, Fernando Silva <fms2...@gmail.com>escreveu:
>
> > Só para o caso de não ter ficado claro, X < Y
>
> >> Em 12 de dezembro de 2010 20:29, Fernando Silva <fms2...@gmail.com>escreveu:
>
> >> Bem, tudo que foi falado está correto, no caso, tenta resolver a questão
> >>> sabendo que:
>
> >>> movzXY => Move um valor de X bits para um registrador de Y bits,
> >>> completando com 0s a esquerda
> >>> movsXY => Move um valor de X bits para um registrador de Y bits,
> >>> completando o número repetindo o bit do sinal em todos os bits a esquerda.
>
> >>> Se continuar com dúvidas na questão é só falar.
>
> >>> Em 12 de dezembro de 2010 20:17, Renan - Genééésio - <
> >>> rengene...@gmail.com> escreveu:
>
> >>> Só pra completar: nesse caso aí, ele tá empilhando na main 2 bytes e tá
> >>>> pegando como parâmetro na função f os mesmos 2 bytes, o que significa que na
> >>>> conversão deste código pra C, a função f recebe como parâmetro um dado do
> >>>> tipo short int e armazena em %ecx e um parâmetro de 4 bytes do tipo int que
> >>>> ele armazena em %ebx. (int = 4 bytes, short = 2 bytes)
> >>>> --
> >>>> Atenciosamente,
> >>>> Renan Iglesias - Genésio -
> >>>>http://www.dcc.ufrj.br/~genesio<http://www.dcc.ufrj.br/%7Egenesio>
>
> >>>> Em 12 de dezembro de 2010 20:03, Daniel Daim <dand...@gmail.com>escreveu:
>
> >>>> Preste atenção que o comando que completa com 0 não preserva sinal,
> >>>>> então se o número for negativo, vai passar a ser um outro número e será
> >>>>> positivo.
>
> >>>>> 2010/12/12 Daniel Daim <dand...@gmail.com>
>
> >>>>> Stefan,
>
> >>>>>> se não me engano, esses comandos movem o valor de um registrador para
> >>>>>> outro com características especiais.
>
> >>>>>> O movzbl, por exemplo, move um registrador de byte para long
> >>>>>> completando com 0.
> >>>>>> Exemplo:
> >>>>>> digamos, hipoteticamente, que um registrador do tipo byte guardasse 4
> >>>>>> bits e estivesse guardando '0110'. E o registrador long guardasse 8 bits. Ao
> >>>>>> usar o comando movzbl ele faria o valor do registrador de 8 bits ser: 0000
> >>>>>> 0110 fazendo o valor do registrador byte ser preservado.
>
> >>>>>> O movswl é a mesma coisa, só que ele preserva sinal, completando com 1
> >>>>>> (se o bit mais significativo for 1) e com 0 (se o bit mais significativo for
> >>>>>> 0). Só que, nesse caso, vamos trabalhar com conversão de registrador de tipo
> >>>>>> word para long.
>
> >>>>>> Basta você saber o tamanho de cada registrador para entender o que vai
> >>>>>> ficar setado após o comando.
>
> >>>>>> Espero ter ajudado.
>
> >>>>>> Abraço,
>
> >>>>>> 2010/12/12 Stefan Teixeira <stefa...@gmail.com>

Fernando Silva

unread,
Dec 14, 2010, 10:43:48 AM12/14/10
to comp...@googlegroups.com
Só para comentar que eu errei um detalhe, aonde é 24 no código, é 40 na verdade, e o resultado que dá de saida é -10
Reply all
Reply to author
Forward
0 new messages