Я создал этот простой и бессмысленный код сборки (Y86), чтобы понять, насколько я понимаю все, что происходит в стеке, когда используются инструкции, pushl, popl и ret.Правильно ли я понимаю стек в этом коде сборки Y86?
Как я уже сказал, этот код бессмыслен, он просто предназначен для тестирования/обучения. Хотя, все адреса памяти были правильно (надеюсь) рассчитаны и не являются случайными.
код Узел состоит в следующем:
| .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
Ниже мой лучший рисовать стек и объяснить, что каждый шаг (инструкция) делает со стеком. Обратите внимание, что я использовал SP и BP для ссылки на% esp и% ebp соответственно, потому что они используются много и упрощают чтение.
Я хочу знать, есть ли у меня все выше справа или если я что-то пропустил. Пожалуйста, не стесняйтесь копировать/вставлять все, что захотите, и исправить некоторые шаги в вашем ответе.
Также обратите внимание, что мое понимание этого очень важно, у меня есть экзамен в понедельник, для которого мне нужно быть готовым, и я бы хотел получить лучший ответ, который вы можете мне дать. В зависимости от ваших ответов я мог бы (или нет) задать некоторые связанные вопросы, которые мы позаботимся в разделе комментариев.
- 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)
На самом деле я не знаю, что используется «обозначение»:/В этом примере я всегда, хотя 0x13 собирался быть сохранен в [0x2E, 0x2D, 0x2C, 0x2B], для меня это имело больше смысла. Это привело бы меня к другому вопросу, если бы кто-то ответил мне, что «у вас все в порядке»: Почему, черт возьми, мы оставляем пустой блок в [0x32, 0x31, 0x30, 0x2F]? –
Это объясняет, почему вы проиллюстрировали это так же, как и вы, но обратите внимание, что стек только/растет/вниз (т. Е. Новый элемент ниже последнего), что не означает, что сами элементы также сохраняются в обратном порядке. A (4-байтовый) элемент в x всегда сохраняется в x, x + 1, x + 2, x + 3. Реверсирование этого для стека также означает, что вы не можете легко использовать адреса из стека в «нормальном» коде. Что касается пустого блока в нижней части стека: это является следствием того факта, что pushl v хранит v в% esp-4 вместо% esp.Конечно, во многих случаях вы можете избежать этого, изменив начальное значение% esp. – mweerden