Pergunta

Eu criei este código simples e montagem inútil (Y86) para ver se eu entender tudo o que está acontecendo na pilha quando as instruções de chamar, pushl, popl e ret são utilizados.

Como eu disse, este código é inútil, é apenas para fins de aprendizagem / teste. Embora, todos os endereços de memória foram corretamente (esperança), calculado e não são aleatórios.

O código de montagem é a seguinte:

     | .pos 0
0x00 |   irmovl Stack, %esp
0x06 |   rrmovl %esp, %ebp
0x08 |   irmovl $5, %eax
0x0E |   call func
0x13 |   halt
0x14 | func:
0x14 |   pushl %ebp
0x16 |   rrmovl %esp, %ebp
0x18 |   pushl %eax
0x1A |   popl %eax
0x1C |   popl %ebp
0x1E |   ret
     | .pos 50
0x32 | Stack: .long 0

O seguinte é o meu melhor para desenhar uma pilha e explicar o que cada passo (instrução) faz com a pilha. Por favor, note que eu usei SP e BP para se referir% esp e% ebp respectivamente porque eles são usados ??muito e faz com que seja mais fácil de ler.

O que eu quero saber é se eu tenho tudo acima, à direita ou se eu perdi alguma coisa. Sinta-se livre para copiar / colar o que quiser e corrigir alguns etapa (s) em sua resposta.

Observe também que o meu entendimento isso é muito importante, eu tenho um exame segunda-feira para que eu preciso estar preparado e eu gostaria que a melhor resposta que você pode me dar. Dependendo de suas respostas, eu poderia (ou não) tenho algumas perguntas relacionadas que devemos tomar cuidado na seção de comentários.

- INSTRUCTION: irmovl Stack, %esp
- INSTRUCTION: rrmovl %esp, %ebp
  1) Point %esp (SP) and %ebp (BP) to Stack

     |  ...  |
0x2E |-------|
     |       |
0x32 |-------| <--- SP & BP

- INSTRUCTION: irmovl $5, %eax
  1) Sets %eax = 5

- INSTRUCTION: call func
  1) Decrements SP by 4 (0x32 -> 0x2E)
  2) Saves return address (0x13) in memory location pointed by SP (0x2E)
  3) Jumps to "func" memory address (0x14)

     |  ...  |
0x2A |-------|
     | 0x13  |
0x2E |-------| <--- SP
     |       |
0x32 |-------| <--- BP

- INSTRUCTION: pushl %ebp
  1) Decrements SP by 4 (0x2E -> 0x2A)
  2) Saves BP value (0x32) in memory location pointed by SP (0x2A)

     |  ...  |
0x26 |-------|
     | 0x32  |
0x2A |-------| <--- SP
     | 0x13  |
0x2E |-------|
     |       |
0x32 |-------| <--- BP

- INSTRUCTION: rrmovl %esp, %ebp
  1) Sets BP = SP (0x32 -> 0x2A)

     |  ...  |
0x26 |-------|
     | 0x32  |
0x2A |-------| <--- SP & BP
     | 0x13  |
0x2E |-------|
     |       |
0x32 |-------|

- INSTRUCTION: pushl %eax
  1) Decrements SP by 4 (0x2A -> 0x26)
  2) Saves %eax value (5) in memory location pointed by SP (0x26)

     |  ...  |
0x22 |-------|
     |   5   |
0x26 |-------| <--- SP
     | 0x32  |
0x2A |-------| <--- BP
     | 0x13  |
0x2E |-------|
     |       |
0x32 |-------|

- INSTRUCTION: popl %eax
  1) Saves value (5) in memory location pointed by SP (0x26) in %eax
  2) Increments SP by 4 (0x26 -> 0x2A)

     |  ...  |
0x22 |-------|
     |   5   |
0x26 |-------|
     | 0x32  |
0x2A |-------| <--- SP & BP
     | 0x13  |
0x2E |-------|
     |       |
0x32 |-------|

- INSTRUCTION: popl %ebp
  1) Saves value (0x32) in memory location pointed by SP (0x2A) in %ebp
  2) Increments SP by 4 (0x2A -> 0x2E)

     |  ...  |
0x22 |-------|
     |   5   |
0x26 |-------|
     | 0x32  |
0x2A |-------|
     | 0x13  |
0x2E |-------| <--- SP
     |       |
0x32 |-------| <--- BP

- INSTRUCTION: ret
  1) Jumps to memory address (0x13) in memory location pointed by SP (0x2E)
  2) Increments SP by 4 (0x2E -> 0x32)
Foi útil?

Solução

Tanto quanto eu posso dizer-lhe que tem tudo certo.

Um ponto menor que posso fazer é que é provavelmente mais intuitivo para escrever os endereços acima do valor a esses endereços. Ou seja:

0x2E |-------|
     | 0x13  |
0x32 |-------|

A razão é que a gama de endereços cobrindo o valor (0x2E, 0x2F, 0x30, 0x31) dirige-se para o próximo 0x32 endereço.

Claro, você pode querer usar a notação esperado pelo seu professor ao fazer o exame.

Outras dicas

Você acertou.

O que você está fazendo está exercendo uma função chamada usando convenções de chamada pelo callee padrão, criando um quadro para o receptor. Você, então, realizar um empurrão simples e pop de um registo antes de retornar para o chamador. Isso é totalmente correto e seu entendimento está correto (consulte http: //y86tutoring.wordpress .com / 2012/10/31 / funcionando-stacks / para detalhes)

Tudo parece bom. Apenas sugestão é que você não precisa definir uma palavra 0x0000 na pilha. Basta definir o rótulo Stack teria feito isso.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top