Почему присваивается мусор?

442
21 января 2017, 11:45

здравствуйте, начинаю въезжать в ассемблер, придумываю себе простой код для примера:

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

Answer 1

Во-первых, даже если переменная i предшествует массиву arr в памяти, все равно никто вам не гарантирует, что переменная i будет расположена в памяти вплотную с массивом arr.

Во-вторых, реализация имеет полную свободу выбора порядка расположения локальных переменных в кадре стека функции. Реализация запросто может расположить их в порядке объявления, но в направлении роста стека, которое в подавляющем большинстве платформ - сверху-вниз, т.е. в порядке убывания адресов. То есть в натуральном порядке возрастания адресов, переменная i на самом деле будет располагаться после массива arr, а не перед ним. Если компилятор сохранил ваш порядок, то через arr[-1] вы скорее попадете в d, а не в i. Однако уже ваш пример показывает, что порядок сохранен не был.

В-третьих, понятное дело, что ничего подобного в языке С сделать нельзя в принципе. Никто вам в С не разрешал не просто доступаться к arr[-1], а даже вычислять положение arr[-1] в памяти. Не говоря о ваших совершенно не обоснованных ожиданиях на тему порядка расположения переменных в памяти.

READ ALSO
Числовые ряды C++

Числовые ряды C++

Есть задание

354
Содержит ли данный код UB?

Содержит ли данный код UB?

Содержит ли данный код UB?

279
Работа с потоками boost

Работа с потоками boost

Задача: параллельно читать файлы и выводить в консоль имя файла и цифру из файла

312