Я анализирую разборку следующей (очень простой) программы на C в GDB на X86_64.
int main()
{
int a = 5;
int b = a + 6;
return 0;
}
Я понимаю, что в X86_64 стек растет. То есть вершина стека имеет более низкий адрес, чем нижняя часть стека. Ассемблер из вышеуказанной программы выглядит следующим образом:
Dump of assembler code for function main:
0x0000000000400474 <+0>: push %rbp
0x0000000000400475 <+1>: mov %rsp,%rbp
0x0000000000400478 <+4>: movl $0x5,-0x8(%rbp)
0x000000000040047f <+11>: mov -0x8(%rbp),%eax
0x0000000000400482 <+14>: add $0x6,%eax
0x0000000000400485 <+17>: mov %eax,-0x4(%rbp)
0x0000000000400488 <+20>: mov $0x0,%eax
0x000000000040048d <+25>: leaveq
0x000000000040048e <+26>: retq
End of assembler dump.
Я понимаю, что:
- Мы помещаем базовый указатель в стек.
- Затем мы копируем значение указателя стека в базовый указатель.
- Затем мы копируем значение 5 в адрес
-0x8(%rbp)
. Поскольку в int 4 байта, не должно ли это быть по следующему адресу в стеке, который является-0x4(%rbp)
, а не-0x8(%rbp)
?. - Затем мы копируем значение в переменную
a
в%eax
, добавляем 6, а затем копируем значение в адрес в-0x4(%rbp)
.
Используя этот рисунок для справки:
(источник: thegreenplace.net)
похоже, что стек имеет следующее содержимое:
|--------------|
| rbp | <-- %rbp
| 11 | <-- -0x4(%rbp)
| 5 | <-- -0x8(%rbp)
когда я ожидал этого:
|--------------|
| rbp | <-- %rbp
| 5 | <-- -0x4(%rbp)
| 11 | <-- -0x8(%rbp)
что, как кажется, имеет место в сборке "7-понимание-по-обучению", где они показывают сборку:
(gdb) disassemble
Dump of assembler code for function main:
0x0000000100000f50 <main+0>: push %rbp
0x0000000100000f51 <main+1>: mov %rsp,%rbp
0x0000000100000f54 <main+4>: mov $0x0,%eax
0x0000000100000f59 <main+9>: movl $0x0,-0x4(%rbp)
0x0000000100000f60 <main+16>: movl $0x5,-0x8(%rbp)
0x0000000100000f67 <main+23>: mov -0x8(%rbp),%ecx
0x0000000100000f6a <main+26>: add $0x6,%ecx
0x0000000100000f70 <main+32>: mov %ecx,-0xc(%rbp)
0x0000000100000f73 <main+35>: pop %rbp
0x0000000100000f74 <main+36>: retq
End of assembler dump.
Почему значение b
помещается в более высокий адрес памяти в стеке, чем a
, когда a
явно объявлен и инициализирован первым?