Dúvida questão 2 Lab 3

7 views
Skip to first unread message

Stefan Teixeira

unread,
Dec 6, 2010, 4:48:33 PM12/6/10
to Comp-Prog
O que está errado nesse programa afinal?
Não entendi direito esse andl de -16 (pra que???) e esse subl é pra reservar espaço na pilha né?
To meio enferrujado com esses códigos, se alguém puder dizer +- o que o programa tá fazendo, ficaria muito grato.

.text
.globl multiplica
multiplica:
    pushl    %ebp
    movl    %esp, %ebp
    movl    12(%ebp), %eax
    imull    8(%ebp), %eax
    imull    16(%ebp), %eax
    imull    20(%ebp), %eax
    popl    %ebp
    ret
.LC0:
.string    "%d\n"
.text
.globl main
main:
    pushl    %ebp
    movl    %esp, %ebp
    andl    $-16, %esp
    subl    $16, %esp
    movl    $400, 12(%esp)
    movl    $300, 8(%esp)
    movl    $200, 4(%esp)
    movl    $100, (%esp)
    call    multiplica
    movl    %eax, 8(%esp)
    movl    $.LC0, 4(%esp)
    movl    $1, (%esp)
    call    __printf_chk
    leave
    ret

Fernando Silva

unread,
Dec 6, 2010, 5:13:28 PM12/6/10
to comp...@googlegroups.com
Bem, vamos por partes:

O caso do andl -16, é como eu respondi na outra dúvida que tiveram ainda agora, eu não tenho 100%, mas acredito que seja uma instrução que o compilador adicionou para "ajustar" a pilha, repare que ela aparece sempre ao início da função main, no caso ele não influência na lógica do algoritmo que foi descrito.

Quanto ao que o programa faz, vou quebrar ele em partes para tentar explicar melhor, começando pela main(vou pular as instruções até o andl $-16):

    subl    $16, %esp -> Reservo 16 espaços na pilha, no caso, espaço para 4 inteiros
    movl    $400, 12(%esp) -> guardo o valor inteiro 400 na posição dada
    movl    $300, 8(%esp) -> guardo o valor inteiro 300 na posição dada
    movl    $200, 4(%esp) -> guardo o valor inteiro 200 na posição dada
    movl    $100, (%esp) -> guardo o valor inteiro 100 na posição dada
    call    multiplica -> Chamo a função multiplica

Bem, só de olhar esse pedaço de código em separado, parece que esses valores inteiros estão sendo passados como argumentos para a função multiplica que está sendo chamada, quando analisar a função, veremos que é exatamente isso.

    movl    %eax, 8(%esp) -> Movo o valor de EAX para a posição dada na pilha
    movl    $.LC0, 4(%esp) -> Movo o endereço da string definida acima("%d\n") para a pilha
    movl    $1, (%esp) -> Movo o inteiro 1 para a pilha
    call    __printf_chk -> chamo a função __printf_chk

No caso aqui, estou novamento empilhando parametrôs de uma função, no caso a __printf_chk, que só de olhar o código, sem o enunciado, deve funcionar de forma bem similar ao printf

No caso os parametrôs são:
1) "%d\n", que se lembramos de comp1 é a string que temos que passar para o printf imprimir um inteiro na tela e realizar uma quebra de linha
2) o valor que estava em EAX, que no caso vai ser um inteiro que é resultante da função multiplica, como veremos depois
3) e esse valor inteiro 1, que(como eu acabei de descobrir) é uma flag usada na função, deêm uma procurada pelo nome da função no google que teve ter uma explicação boa de para que serve essa flag.

Bem, isso é a main, vamos olhar a multiplica(vou pular as linhas de ajuste do EBP porque são aquelas clássicas de todas as funções):

    movl    12(%ebp), %eax -> movo o argumento que estava nessa posição, no caso o 2º argumento, para EAX
    imull    8(%ebp), %eax -> multiplico o valor de EAX pelo 1º argumento, logo EAX = 1ºarg x 2ºarg
    imull    16(%ebp), %eax -> multiplico o resultado acima pelo 3º argumento
    imull    20(%ebp), %eax -> multiplico o resultado acima pelo 4º argumento

Esse resultado fica guardado em EAX, logo, EAX = 100*200*300*400, e no caso como o EAX é usado como argumento do print, ele está meio que funcionando como um registrador que guarda o valor de retorno da função nesse caso.


Espero que tenha ficado mais claro agora, qualquer coisa é só falar.

Stefan Teixeira

unread,
Dec 6, 2010, 5:28:35 PM12/6/10
to comp...@googlegroups.com
Ficou sim, só que eu me perdi na disposição da pilha. Se na função multiplica ele ajusta o ebp pra apontar pro mesmo local que o esp, pq eu to referenciando o primeiro parametro como 8(ebp), se o primeiro estava em (esp)?

Fernando Silva

unread,
Dec 6, 2010, 5:45:37 PM12/6/10
to comp...@googlegroups.com
Você tá esquecendo do detalhe do EIP, vou dar um passo a passo da pilha aqui para você:

OBS: Na pilha que eu vou desenhar, o mais acima é o topo da pilha

logo antes de chamar o multiplica:
EBP = ?

Pilha:
Arg1 <- ESP
Arg2
Arg3
Arg4

Logo após chamar o multiplica:

EBP = ?

Pilha:
EIP <- ESP
Arg1
Arg2
Arg3
Arg4

Ai empilhamos o EBP

EBP = ?

Pilha:
EBP(valor = ?) <- ESP
EIP
Arg1
Arg2
Arg3
Arg4

Ai igualamos EBP = ESP

Pilha:
EBP(valor = ?) <- ESP & EBP
EIP
Arg1
Arg2
Arg3
Arg4

Logo, o Arg1 está no ESP + 8

Stefan Teixeira

unread,
Dec 6, 2010, 5:53:12 PM12/6/10
to comp...@googlegroups.com
Ah tranquilo, valeu!
Reply all
Reply to author
Forward
0 new messages