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