Как языки программирования работают со стеком?

Пожалуйста, не рассказывайте в сотый раз про стопки тарелок. Я не могу найти ответ на вопрос: как достаются нужные данные из стека.

Например, как я узнал, простые данные в Rust хранятся в стеке. Вот пример кода:

fun main() {

let a: i32 = 1;

let b: i32 = 2;

let c: i32 = a + 1;

}

Каким образом для инициализации переменной С Rust достанет значение А, если оно закрыто сверху значением переменной B?

Предполагаемый ответ оставил в комментариях.

55
19 комментариев

Фраза "простые данные хранятся в стеке" корректна, но может вводить в заблуждение. Так как это не классический стек, где можно забрать только последний элемент. Стек здесь противопоставляется такому понятию как "куча". В общем, стек переменных позволяет обращаться к нескольким элементам.

6

Комментарий недоступен

3

Спасибо! Это поможет

1

Итак, вот, что я узнал:
Во-первых, стек используется для хранения переменных области видимости. В примере справа представлен код на ассемблере. Для каждой конкретной функции выделяется свой стэк-фрейм, то есть область стека, которую можно определить на этапе компиляции (отсюда, видимо, то, что только простые типы данных хранятся в стеке, а, например, строки - нет (не может определить размер стек-фрейма). Размер фрейма определяется в строчке 25 и 15. Мы добавляем смещение к началу текущего стек-фрейма, так что в функции sec для определения собственного фрейма используется уже rsp, смещенный на 32 байта. Смещением мы вычитаем от конца стека, так что можно сказать, что стек "растет вниз". Уточню - rsp - регистр, хранящий адрес последнего элемента, помещенного в стек. Так что в самом начале мы используем его.
Во-вторых, для обращения к переменным компилятор запоминает смещение адреса каждой из них (rbp - 4, -8 и так далее). На сколько я понял, на этапе выполнения программы эти смещения никак меняться не могут, поэтому такое возможно.
В-третьих, опять же, на сколько понял, главная задача стека - быстро запомнить смещения для каждого стек-фрейма.

3

Комментарий недоступен

В-третьих, опять же, на сколько понял, главная задача стека - быстро запомнить смещения для каждого стек-фрейма

Стек ничего не запоминает. "Задача"стека быстро выделять и освоюождать память. Выделить фрейм на стеке гораздо быстрее чем просить у ос память в хипе.

Вот мне интересно почему во многих современных языках инициализация переменных происходит таким образом:
let a: i32 = 1;Не проще ли было бы как в Си-подобных:
i32 a = 1;Не просто так ведь ввели такой синтаксис в Rust и других молодых языках. Интересно было бы узнать почему

2