здравствуйте, начинаю въезжать в ассемблер, придумываю себе простой код для примера:
auto hi() {
int i = 2;
int arr[]={1,1,1,1,1};
int d = arr[-1];
}
я считал, что d должно присвоиться значение 2... ну мол i и arr лежат рядом последовательно, выравнивания нету в стеке. однако там мусор, ассемблерный выхлоп помог понять что 2 не должно было присвоиться:
push %rbp
mov %rsp,%rbp
movl $0x2,-0x4(%rbp)
movl $0x1,-0x20(%rbp)
movl $0x1,-0x1c(%rbp)
movl $0x1,-0x18(%rbp)
movl $0x1,-0x14(%rbp)
movl $0x1,-0x10(%rbp)
mov -0x24(%rbp),%eax
mov %eax,-0x8(%rbp)
nop
pop %rbp
retq
но возникла пару других вопросов: почему d лежит именно в смещении -0x8 относительно rbp? переменная i лежит в -0x4 ( это понятно т.к. самая первая переменная в стеке ), почему массив начинается не следом, с -0x8, а с -0x20 и идет до -0x10? я думал, что i будет лежать в -0x4, далее массив начиная с -0x8 и так далее, а в переменную d запишется как раз то, что было до -0x8 т.е. -0x4
Во-первых, даже если переменная i
предшествует массиву arr
в памяти, все равно никто вам не гарантирует, что переменная i
будет расположена в памяти вплотную с массивом arr
.
Во-вторых, реализация имеет полную свободу выбора порядка расположения локальных переменных в кадре стека функции. Реализация запросто может расположить их в порядке объявления, но в направлении роста стека, которое в подавляющем большинстве платформ - сверху-вниз, т.е. в порядке убывания адресов. То есть в натуральном порядке возрастания адресов, переменная i
на самом деле будет располагаться после массива arr
, а не перед ним. Если компилятор сохранил ваш порядок, то через arr[-1]
вы скорее попадете в d
, а не в i
. Однако уже ваш пример показывает, что порядок сохранен не был.
В-третьих, понятное дело, что ничего подобного в языке С сделать нельзя в принципе. Никто вам в С не разрешал не просто доступаться к arr[-1]
, а даже вычислять положение arr[-1]
в памяти. Не говоря о ваших совершенно не обоснованных ожиданиях на тему порядка расположения переменных в памяти.
Фрилансер или Digital-агентство - Как сделать правильный выбор?
Задача: параллельно читать файлы и выводить в консоль имя файла и цифру из файла
Имеется такая учебная задача: