2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу Пред.  1, 2, 3, 4, 5  След.
 
 Re: Вопрос по работе компилятора C++
Сообщение28.02.2017, 14:52 


09/05/10
122
Ростов-на-Дону
aa_dav в сообщении #1195980 писал(а):
она просто берет и (сама) добавляет их к стеку.

Ничего она не добавляет, они и так уже в стеке.
Alex Fox, почитайте какую-нибудь книгу по ассемблеру, в частности, про создание стекового кадра и про соглашения о вызовах функций. Тогда Вам станет понятно, что никакого подсчёта локальных переменных функций ни компилятором, ни транслятором и даже линковщиком не происходит.
По умолчанию размер стека равен 1Мб, но его можно изменить.
mustitz в сообщении #1195987 писал(а):
у которого есть доступ ко всем объектным файлам. Он обладает всей полнотой информации и решает, какие секции будут в исполняемом файле, и что по какому смещению будет располягаться. Что надо поместить в глобальную память, что в константную, если такая есть, что забито нулями а что будет проинициализировано при старте программы,

:lol:
Да, память подсчитывает линкер, всё верно. Точней, размер самой программы.
mustitz в сообщении #1195987 писал(а):
Ну а под стек память уже выделяется в процессе выполнения программы с использованием механима виртуальных страниц. При обращении к памяти, которая не замаплена на физическую, происходит прерывание, по которому операционка выделяет новый фрагмент памяти, подкладывает его на место стека и возвращает выполнение той инстукции, которая выполнялась.

А это здесь уже лишнее.

 Профиль  
                  
 
 Re: Вопрос по работе компилятора C++
Сообщение28.02.2017, 15:02 


11/12/14
893
Tod Leben в сообщении #1195989 писал(а):
Ничего она не добавляет, они и так уже в стеке.


Нет, сами они там не появятся, SP еще не настроен в этом месте должным образом, ну и BP, если мы говорим про x86.
Надеюсь понятно, что я под такими действиями и имею ввиду "добавить их в стек". Кроме того, что в иных языках есть еще конструкторы и всякое такое.

 Профиль  
                  
 
 Re: Вопрос по работе компилятора C++
Сообщение28.02.2017, 15:16 


09/05/10
122
Ростов-на-Дону
aa_dav в сообщении #1195992 писал(а):
Нет, сами они там не появятся, SP еще не настроен в этом месте должным образом.

SP настраивается только на стековый кадр. Переменные помещаются в стек до вызова функции. Затем, туда помещается
сегментный адрес и смещение того места, откуда происходит вызов, после чего и происходит переход на адрес вызываемой функции. Почитайте тоже, что я рекомендовал выше.
Можно и не использовать сам вызов на прямую, не использовать команду "CALL" , а обойтись командой "JMP" или командой "RET",
как для вызова, так и для возврата на прежний адрес. Но это только на ассемблере, речь не идёт о "C"

 Профиль  
                  
 
 Re: Вопрос по работе компилятора C++
Сообщение28.02.2017, 15:18 


10/04/12
705
Tod Leben в сообщении #1195989 писал(а):
По умолчанию размер стека равен 1Мб, но его можно изменить.


Где такое умолчание? Если брать Linux Kernel, то там гарантированный размер стека обычно 8k, но можно уменьшить до 4k.

Если брать юзерспейс, то ulimit -s, на моей машине возвращает 8 Mb. Но легко можно увеличить хоть до бескончности, тут больше стоит задача отлавливать программы, которые входят в бесконечную рекурсию, чтобы они не завалили систему.

 Профиль  
                  
 
 Re: Вопрос по работе компилятора C++
Сообщение28.02.2017, 15:20 
Аватара пользователя


05/08/11
36
Калининград
Tod Leben в сообщении #1195989 писал(а):
Alex Fox, почитайте какую-нибудь книгу по ассемблеру

Есть в планах ознакомится вот с это книгой: "Компиляторы: принципы, технологии и инструменты". Говорят, что это классика, хотя не знаю насколько она еще актуальна.

 Профиль  
                  
 
 Re: Вопрос по работе компилятора C++
Сообщение28.02.2017, 15:39 


09/05/10
122
Ростов-на-Дону
mustitz в сообщении #1195996 писал(а):
Где такое умолчание?

В "MASM". Я напишу свой транслятор, предположим, и там будет ровно то, о чём вы говорите
Alex Fox в сообщении #1195997 писал(а):
Но легко можно увеличить хоть до бескончности,

Это на сколько мне ума хватит. А о юзерспейс и маппинг речи здесь не шло.
Alex Fox в сообщении #1195997 писал(а):
Есть в планах ознакомится вот с это книгой: "Компиляторы: принципы, технологии и инструменты".

Это будет Вашим следующим шагом, если освоите для начала ассемблер, хотя бы его основы. Сразу станет понятен механизм
вызова и передачи, да и вообще интересно.

 Профиль  
                  
 
 Re: Вопрос по работе компилятора C++
Сообщение28.02.2017, 15:42 
Аватара пользователя


05/08/11
36
Калининград
Tod Leben в сообщении #1196006 писал(а):
если освоите для начала ассемблер

Может порекомендуете что?

 Профиль  
                  
 
 Re: Вопрос по работе компилятора C++
Сообщение28.02.2017, 15:42 


09/05/10
122
Ростов-на-Дону
Alex Fox в сообщении #1196008 писал(а):
Может порекомендуете что?
Я не знаю, что именно рекомендовать, так как думаю начать лучше наверно с реального режима. Я так начинал. Да я и не профи в этом вопросе. Где-то здесь была тема с рекомендуемой литературой.
Последняя прочитанная мной книга была "Кип Ирвин. Программирование для процессоров Intel". Кажется так она называется. Но, после прочтения я был разочарован, так как знал всё то, о чём в ней было написано. Думаю нужно самостоятельно подбирать себе литературу, исходя из того, что конкретно Вас интересует. По моему опыту, ни в одной книге нет полного изложения всех возможностей ассемблера.
Просмотрю имеющуюся у меня литературу и позже что-нибудь предложу.

 Профиль  
                  
 
 Re: Вопрос по работе компилятора C++
Сообщение28.02.2017, 15:57 


10/04/12
705
Tod Leben в сообщении #1196009 писал(а):
Я напишу свой транслятор, предположим, и там будет ровно то, о чём вы говорите


А при чём тут транслятор, если в ELF-файле нет информации по которой можно посчитать размер стека? Для Linux это один параметр для всей операционной системы.

 Профиль  
                  
 
 Re: Вопрос по работе компилятора C++
Сообщение28.02.2017, 16:30 
Заслуженный участник


20/08/14
11780
Россия, Москва
Для Windows.
При старте программы размер стека описан в заголовке exe файла, а туда помещается именно линкером при компиляции. При старте же дополнительного потока размер стека можно указывать явно - в Win32API есть CreateThread с параметром начального размера стека.

 Профиль  
                  
 
 Re: Вопрос по работе компилятора C++
Сообщение28.02.2017, 16:35 


09/05/10
122
Ростов-на-Дону
mustitz в сообщении #1196014 писал(а):
А при чём тут транслятор, если в ELF-файле нет информации по которой можно посчитать размер стека?

Извините, линковщик. Хотя, сейчас я точно не помню, но есть директива ассемблера, в которой задаётся размер стека. Я не знаком с ELF - файлами, и с Linux тоже не знаком. Все написанные мной программы были под MS-DOS или Windows.
А при чём юзерспейс и маппинг? Речь шла, как я понял, об этапе сборки самой программы, а не о её выполнения. О механизмах лимитирования памяти системой речи не шло. Это мы думаем, что под программу и её компоненты система выделит заявленный объём памяти, а на самом деле это не всегда так. Ещё это зависит от выбранной модели памяти. Короче, в таком случае нужно уточнять конкретно о чём идёт речь! И, размер стека - это забота самого программиста, а не системы или транслятора, или того же линкера.
Так, а теперь ещё раз извиняюсь за то, что ввёл всех в некоторое заблуждение, и себя в том числе. Как там "C" или Unix решают этот вопрос мне пофиг(вероятно подсчётом команд push/pop и call/ret). Я увидел, что речь шла об исполнимом, ассемблерном коде и решил поделиться своим опытом. Всё.

-- Вт фев 28, 2017 17:51:31 --

Dmitriy40 в сообщении #1196024 писал(а):
Для Windows.
При старте программы размер стека описан в заголовке exe файла, а туда помещается именно линкером при компиляции. При старте же дополнительного потока размер стека можно указывать явно - в Win32API есть CreateThread с параметром начального размера стека.

Да! Вот здравый ответ, а то у меня что-то мозг начал дымиться. В модели памяти Windows(flat model), все сегментные регистры настраиваются на один сегмент, за исключением некоторых. Подсчитать размер стека до байта невозможно, если это не какая-нибудь
виртуализация стека. Минимальным размером стека будет наверно параграф.

 Профиль  
                  
 
 Re: Вопрос по работе компилятора C++
Сообщение28.02.2017, 16:59 


10/04/12
705
Dmitriy40 в сообщении #1196024 писал(а):
Для Windows.
При старте программы размер стека описан в заголовке exe файла, а туда помещается именно линкером при компиляции. При старте же дополнительного потока размер стека можно указывать явно - в Win32API есть CreateThread с параметром начального размера стека.


Как по мне крайне неудачное решение. Во-первых, посчитать до байта размер стека, который необходим приложению, в общем случае не представляется возможным. Поэтому значение часто устанавливается от фонаря и не контролируется никак. Ну и если вдруг у клиента размер стека будет превышен последним патчем, то он ничего не в состоянии сделать. Ну кроме как поменять заголовок и захучить CreateThread.

 Профиль  
                  
 
 Re: Вопрос по работе компилятора C++
Сообщение28.02.2017, 17:01 
Заслуженный участник


20/08/14
11780
Россия, Москва
Tod Leben в сообщении #1196027 писал(а):
Минимальным размером стека будет наверно параграф.
Скорее страница (4к), но это зависит от ОС. Точнее указатель то можно настроить с точностью до байта (если не волнует скорость работы, или до 32-х битов), но вот ОС в любом случае выделит целое количество страниц виртуальной памяти. И что будет после исчерпания размера - тоже зависит от ОС, как она разместит области памяти и как отреагирует на переполнение области памяти стека (например состыковав память кода и стека и отключив контроль размера стека и разрешив запись в память кода можно легко получить порчу кода программы при переполнении стека, хорошо что обычно так не делается). Линкер же указывает лишь минимум и максимум требуемого размера стека, не более того. Так что фактически всё отдано на откуп ОС.

-- 28.02.2017, 17:10 --

Насчёт как подсчитать требуемый размер. Обычно ставят конечно "от фонаря", типа мегабайта (дельфи). Но вообще говоря вполне можно пройти по всему дереву возможных вызовов функций и подсчитать максимум требуемого размера стека. Не в общем случае конечно, и уж точно не для рекурсивных программ, но довольно часто. Делается ли это или нет - я не в курсе.
На месте ОС я бы посадил стек под верхнюю границу памяти, а всё остальное снизу, с кучей на самом верху. И тогда стек и куча будут конкурировать за память. А других динамически растущих структур при исполнении вроде бы и нет. Повторю, как оно на самом деле я не в курсе. Проверил дельфи5: код программы сидит по адресу 0x00400000, а стек ниже, по 0x00190000, при размере стека в заголовке exe 0x4000-0x100000 (мин-макс).

 Профиль  
                  
 
 Re: Вопрос по работе компилятора C++
Сообщение28.02.2017, 17:45 


10/04/12
705
Dmitriy40 в сообщении #1196035 писал(а):
На месте ОС я бы посадил стек под верхнюю границу памяти, а всё остальное снизу, с кучей на самом верху. И тогда стек и куча будут конкурировать за память. А других динамически растущих структур при исполнении вроде бы и нет. Повторю, как оно на самом деле я не в курсе. Проверил дельфи5: код программы сидит по адресу 0x00400000, а стек ниже, по 0x00190000, при размере стека в заголовке exe 0x4000-0x100000 (мин-макс).


В старых 32-битных реализациях Linux так и было. Но... есть ещё файлы проецируемые в память, есть разделяемая память, там что определынные сложности таки есть.

Ну... а в 64-битном адресном пространстве нет проблемы зарегать под стек пару терабайт. Вопрос в другом. В случае, если в какой-то проге таки произойдёт бесконечная рекурсия, то такая программа может быстро выжрать все ресурсы плюс своп, что приведёт к тому, что вся система станет нестабильной, что не есть гуд. Серверам надо работать стабильно, да и для юзверя такая ситуация не очень приятна. Поэтому есть хорошее решение ограничить размер стека у всех приложений для безболезненного отлавливания таких ситуаций. Ну а программист должен сам стараться не злоупотреблять выделениями в стеке. Для userspace в Linux это значение настраивается и часто по умолчанию равно 8M. Но если уж найдётся программа, которой этого будет мало в силу каких-то причин, то это значение можно увелить вплоть до unlimited.

-- 28.02.2017, 16:48 --

Dmitriy40 в сообщении #1196035 писал(а):
Но вообще говоря вполне можно пройти по всему дереву возможных вызовов функций и подсчитать максимум требуемого размера стека. Не в общем случае конечно, и уж точно не для рекурсивных программ, но довольно часто.


Ещё проблемы создадут callback-и, виртуальные функции, есть выделения на стеке, зависящие от параметров.

 Профиль  
                  
 
 Re: Вопрос по работе компилятора C++
Сообщение28.02.2017, 17:53 
Заслуженный участник
Аватара пользователя


16/07/14
9151
Цюрих
mustitz в сообщении #1196053 писал(а):
В случае, если в какой-то проге таки произойдёт бесконечная рекурсия, то такая программа может быстро выжрать все ресурсы плюс своп, что приведёт к тому, что вся система станет нестабильной, что не есть гуд
А в чем принципиальная разница между выжиранием всей памяти в стеке и в куче?

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 61 ]  На страницу Пред.  1, 2, 3, 4, 5  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group