Перейти к содержанию
    

Как создаются инициализированные переменные в памяти ?

22 минуты назад, Variant99 сказал:

Изначально речь шла о том, что я попросил показать на практике предположение о том, что Сишный компилятор может самопроизвольно упаковать в биты байтовую (uint8_t) неконстантную переменную в RAM только на основании того, что инициализующие её значения равны 0 или 1. 

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

1) от этого не меняется результирующий алгоритм работы программы;

2) эти данные не объявлены со спецификатором volatile.

И если у вас в программе написано например:

int Func()
{
  static char t = {0, 1, 1, 1, 0, 1};
  int i = t[0];
  i += t[1];
  i += t[2];
  i += t[3];
  return i;
}

то из этого вовсе не следует, что в результирующем коде функции Func() будут присутствовать 4 команды чтения из t[] и 3 команды сложения. Вполне возможно, что вся функция будет состоять всего из двух команд:

MOVS R0, #3
BX LR

и даже не будет израсходовано ни байта ОЗУ. И в результирующем образе не будет вообще никаких инициализаторов.

 

Соответственно компилятор может и упаковывать и как-то иначе трансформировать данные в массивах программы. И чем умнее компилятор - тем больше вероятность что он так сделает. И даже если он не делает этого сейчас в данный момент, то может это сделать при дальнейших перекомпиляциях исходников. Даже без изменения ключей компиляции или версии компилятора.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 12/15/2022 at 10:49 AM, jcxz said:

То что "оптимизация отключена" как правило говорит о крайне низком качестве как самих исходников так и их автора, как программиста. Если она отключена именно всегда.

На этапе отладки мы всегда отключаем оптимизацию. Т.к при включенной оптимизации отладчик скачет по программе как-то очень хаотично (оно и понятно).  В готовом изделии включаем конечно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 минуты назад, jcxz сказал:

Соответственно компилятор может и упаковывать и как-то иначе трансформировать данные в массивах программы.

Вот я и просил показать на практическом примере, как "умный" компилятор умудряется упаковать БАЙТОВЫЙ и неконстантный массив в ОЗУ в БИТЫ только на том основании, что инициализующие значения 0 и 1. 
То есть, не "может/не может", а конкретно пример, байты в биты в ОЗУ. При том, что битовые операции в ОЗУ в байт-ориентированной машине выполняются не самым оптимальным образом.

Выходит, чем умнее компилятор, тем тупее кодописатель? 🙂

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

8 минут назад, Variant99 сказал:

То есть, не "может/не может", а конкретно пример, байты в биты в ОЗУ. При том, что битовые операции в ОЗУ в байт-ориентированной машине выполняются не самым оптимальным образом.

Из исходного сообщения никак не видно - используется тот массив как ОЗУ, или автор его просто забыл написать const? Очень многие халтурщики просто не пишут const, используя такие массивы по факту только на чтение. То что ТС не может найти инициализатора в результирующем образе как раз косвенно говорит в пользу такого варианта.

Также не видно - в какой именно памяти этот массив объявлен.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Две страницы бессмысленных букв от гуру программирования.

Cделайте свой код и запускаёте его вместо main.

Там исправьте, что нужно в этой таблице и потом перейдите на оригинальный main.

Работы на час.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 12/15/2022 at 11:43 AM, x893 said:

Две страницы бессмысленных букв от гуру программирования.

Cделайте свой код и запускаёте его вместо main.

Там исправьте, что нужно в этой таблице и потом перейдите на оригинальный main.

Работы на час.

Запущу пожалуй сей девайс под отладчиком. Пусть исходника у меня и нет, но в ОЗУ при работающей программе эта последовательность нулей и единичек точно отыщется. Вот и будет мне счастье пока товарищ не выйдет с больничного.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

10 минут назад, x893 сказал:

Cделайте свой код и запускаёте его вместо main. потом перейдите на оригинальный main.

Угу, теоретически выглядит красиво. Но на практике еще нужно отыскать в бинарнике эту точку входа в маин. Там одного только поиска - на час красноглазения 🙂 , причем еще не факт. В бинарнике то не подписано, где маин начинается 🙂 

29 минут назад, jcxz сказал:

просто забыл написать const?

"Ах может, ах если" 🙂 Чего гадать то? Я, кстати, еще на первой странице написал и показал, что компилятор даже с полностью выключенной оптимизацией может инициализующие значения  const-массива запихнуть в операнды машинных инструкций, да так, что хрен найдешь еще. И никакого волшебства! 

9 минут назад, TOG сказал:

в ОЗУ при работающей программе эта последовательность нулей и единичек точно отыщется

Тоже не факт! Все зависит от того, в каком месте кода (в какой функции, глобально или локально) был использован этот массив. Стек вызовов функций может затираться во время работы другими функциями. Да и сам массив в случае const в ОЗУ может не отобразиться, а значения будут использованы через операнды инструкций в регистровом файле ядра.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

27 minutes ago, TOG said:

Запущу пожалуй сей девайс под отладчиком. Пусть исходника у меня и нет, но в ОЗУ при работающей программе эта последовательность нулей и единичек точно отыщется. Вот и будет мне счастье пока товарищ не выйдет с больничного.

Конечно. При входе в main она должна быть в ОЗУ (если в bin её нет).

Но ещё лучше программисту люлей дать, что бы исходный код не хранил на личной флэшке.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Совсем не факт, что при входе в участок, обозначенный как main, искомый массив будет в ОЗУ. Топикстартер так до сих пор и не сообщил, в каком месте текста программы этот массив был объявлен, с какой областью видимости, с  какими квалификаторами хранения. 
В самом простом случае, когда массив будет расположен в начале SRAM, его заполнение значениями произойдет еще задолго до входа в main, это выполнит код из стартапа, в самом начале работы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

По поводу хранения исходников на флешке и унесения их с собой. Ситуацию мы видим только со слов топикстартера, а как оно на самом деле обстоит - не знаем. 
Бывает, кто-то ведет проект от начала и до кончала и не желает, чтобы без ведома в проект кто-то влезал не совсем ровными ручками и чето там "правил". Описание ситуации, что ТС "только видел на мониторе" как бы намекает на подобный расклад. Возможно. Ну а от болезни в наше время никто не застрахован. В конце концов, если того требует производственная необходимость, исходники проекта могут быть высланы по электронке, по вацапу, через вконтактик или через "знакомого курьера".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

29 minutes ago, Variant99 said:

Бывает, кто-то ведет проект от начала и до кончала и не желает, чтобы без ведома в проект кто-то влезал

Мнение рядового программиста мало что значит. Разграничением прав доступа занимается служба безопасности, иногда в лице начальника. Исходный код должен храниться на каком-либо сервере. В противном случае, можно одним махом потерять все наработки, в которые "никто не влезал". В случае потери данных на сервере, отвечать за это будет владелец сервера, в другом случае - сам сотрудник. Система контроля версий Git, например, позволяет настраивать права доступа. Хотя это и её не основная функция.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

2 hours ago, Variant99 said:

Совсем не факт, что при входе в участок, обозначенный как main, искомый массив будет в ОЗУ. Топикстартер так до сих пор и не сообщил, в каком месте текста программы этот массив был объявлен, с какой областью видимости, с  какими квалификаторами хранения. 
В самом простом случае, когда массив будет расположен в начале SRAM, его заполнение значениями произойдет еще задолго до входа в main, это выполнит код из стартапа, в самом начале работы.

0. И что мешает при входе в майн поиском найти (или не найти) нужную последовательность ? И посмотреть где она находится (RAM, Flash) и сделать (или не сделать) замену ?

1. hex -> bin

2. Поиск последовательности.

2а. Нашли - меняем, прошиваем и радуемся.

2б. Не нашли - есть надежда, что в SRAM

3. Доходим до main(), делаем сохранение SRAM в файл и там ищем.

3а. Нашли. Меняем в нужном месте SRAM и проверяем работу. Делаем затычку в свободном месте флэш. Переходим к 4.

3б. Не нашли. Хана.

4. Ждём кнопкодава с исходниками.

Не отнимая время гуру программирования и чтение бессмысленных рассуждений.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

On 12/15/2022 at 3:30 PM, x893 said:

0. И что мешает при входе в майн поиском найти (или не найти) нужную последовательность ? И посмотреть где она находится (RAM, Flash) и сделать (или не сделать) замену ?

Так и сделал. Под отладчиком эта последовательность в ОЗУ сразу нашлась. Исправил, что хотел. Так под отладчиком и работает пока.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 minutes ago, TOG said:

Так и сделал. Под отладчиком эта последовательность в ОЗУ сразу нашлась. Исправил, что хотел. Так под отладчиком и работает пока.

Ну вот ! Можете же.

Теперь сделайте программу, которая будет запускаться перед main(), менять в нужном месте и потом переходить на старый main(). Если конечно есть немного места свободного во флэш.

И тогда RESET не страшен.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

может, я что-то не понимаю, но как вы в готовом бинарнике без исходника найдете вход в main? Быть может, вы  имеете ввиду не main, а вектор reset? Это да. Но функция main, которая вызывается после немалого числа операций и сама по себе расположена в нефиксированном месте, её по бинарнику никак не отследить, ибо она ничем не отличается от любой другой функции. 

Хотя... теоретически можно некоторым образом ориентироваться на указатель вершины стека, по его приходу к началу стека, но... довольно грубая ориентировка.

26 минут назад, TOG сказал:

Под отладчиком эта последовательность в ОЗУ сразу нашлась. Исправил, что хотел.

В ОЗУ, да. А во флеше? Нашли место, откуда значения берутся? Потому что до тех пор, пока не исправите во флеше, это будет костыль нерабочий.

45 минут назад, x893 сказал:

И что мешает при входе в майн поиском найти (или не найти) нужную последовательность ?

Можно, плиз, с демонстрацией примера. А то мож я чето не знаю.

45 минут назад, x893 сказал:

hex -> bin

2. Поиск последовательности.

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

Поэтому, можно, плиз, на наглядном примере это показать? А то мож я чего не знаю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...