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

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

23 hours ago, TOG said:

Сотрудник, который сделал эту программу на больничном. У меня есть только МК с прошивкой.

1) Подождать пока выздоровеет.

2) Когда вернется на работу, обяснить что надо изменить, и перекомпилировать.

3) Заставить скопировать исходники на сервер конторы, или где там у вас хранится техдокументация в электронном виде.

4) Затем сотрудника  уволить за профнепригодность (невыполнение п.3 в прошлом).

 

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


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

2 часа назад, TOG сказал:

сделал два проекта в котором массивы нулей и единичек отличаются только первым и последним байтом. И вот так выглядим место в прошивке, где есть отличия.

Странно у вас как-то. Генерили в Кубе проект? Потому как вставлена текстовая отладочная информация в него. 
Как я ранее писал, если вы массив создали, но к нему ни разу не обратились в тексте кода, в сборку этот массив может вообще не вставляться.

Я вот создал чистый проект с таким же массивом единиц и нулей на 180 байт. Видим расположение инициализаторов этого массива по адресу 0x08000234: а 

Idx Name          Size      VMA       LMA       
  5 .data         000000b4  20000000  08000234

а это кусок из hex-файла начиная от адреса 0x08000234 с этими самыми 1 и 0 (последние 2 цифры в каждой строке - контрольная сумма строки, а первые 8 цифр - сигнатура строки и смещение адреса данных)

:1002340001000101010000010000010001010100B1
:1002440000010000010001010100000100000100A3
:100254000101010000010000010001010100000191
:100264000000010001010100000100000100010182
:100274000100000100000100010101000001000073
:100284000100010101000001000001000101010061
:100294000001000001000101010000010000010053
:1002A4000101010000010000010001010100000141
:1002B4000000010001010100000100000100010132
:1002C4000100000100000100010101000001000023
:1002D4000100010101000001000001000101010011
:0402E40000010000
Изменено пользователем Variant99

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


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

32 minutes ago, Variant99 said:

Странно у вас как-то.

У него компилятор armcc. Инициализация bss другая.

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


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

11 часов назад, TOG сказал:

uint8_t data[] = {1,1,1,0,0,0,1,0,1,0,1,1,1,0,0,0,1,0,1,0,1,0,1,0 .. и так далее 180 байт всего};

Я решил поискать эту последовательность в файле прошивки и ничего похожего там не нашел.

А что если компилятор оказался настолько умнее погроммиста, написавшего сиё безобразие, что догадался упаковать биты в байты и сэкономить тем самым 157 байт ОЗУ + ~150 байт флеша? Потому и найти не получается.

:biggrin:

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


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

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

упаковать биты в байты и сэкономить тем самым 157 байт ОЗУ

А такое, извините, бывает? Можно пример показать? Потому как массив объявлен uint8_t, и в байт можно положить любое число во время работы кода, поскольку он не const и как тогда компилятор будет такую ситуевину разруливать - вопрос.

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


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

Технически компилятору это не запрещено, т.к. он не работает с тем, что там понаписал программист. Компилятор обрабатывает текст программы и строит на его основе так называемое наблюдаемое поведение абстрактной машины. Если программист явно не пишет в эти ячейки, нет хитрой логики обработки этих данных - то вполне возможно допустить упаковку. Это банальная оптимизация.

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


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

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

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

Компилятор может видеть например, что в данный массив "ничего не ложится во время работы кода". Только и всего.

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

Также компилятор мог увидеть, что элементы массива используются только в выражениях типа:

data[x] + '0'

И добавить этот прибавляемый '0' ко всем элементам массива, убрав лишнее runtime-сложение. Тогда опять инициализатор будет иным.

 

PS: И + ещё 100500 других вариантов....

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


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

#include "main.hpp"

u8 arr[] = {0, 1, 1, 0, 1, 0, 1, 1};

volatile u32 i;


int main() {
  i = arr[0];
  i = arr[1];
  i = arr[2];
  i = arr[3];
  i = arr[4];
  i = arr[5];
  i = arr[6];
  
  while(1) {
  }
}
0x08000448 4805      LDR  r0, [pc, #20]
0x0800044A 2100      MOVS r1, #0x00
0x0800044C 2201      MOVS r2, #0x01
0x0800044E 6001      STR  r1, [r0, #0x00]
    10:   i = arr[1]; 
0x08000450 6002      STR  r2, [r0, #0x00]
    11:   i = arr[2]; 
0x08000452 6002      STR  r2, [r0, #0x00]
    12:   i = arr[3]; 
0x08000454 6001      STR  r1, [r0, #0x00]
    13:   i = arr[4]; 
0x08000456 6002      STR  r2, [r0, #0x00]
    14:   i = arr[5]; 
0x08000458 6001      STR  r1, [r0, #0x00]
    15:   i = arr[6]; 
    16:    
0x0800045A 6002      STR           r2,[r0,#0x00]
    17:   while(1) { 
0x0800045C E7FE      B             0x0800045C


Вообще массив выкинулся. Больше скажу, даже static const тут не поможет появлению этого чудо-массива во Flash. Разумеется, только атрибут used спасет.

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


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

1 час назад, jcxz сказал:

что в данный массив "ничего не ложится во время работы кода"

1 час назад, jcxz сказал:

упаковать биты в байты

Чето я тут не понял, что во что упаковывается и что выкидывается, на чем экономится. Откуда вдруг биты, если uint8_t - байтовая переменная.

1 час назад, Arlleex сказал:

Если программист явно не пишет в эти ячейки

А если программист создаст указатель и где-то в коде неожиданно присвоит указателю адрес этого массива, да еще не явно, а в результате вычислений, да еще и не отслеживаемых на этапе компиляции, и начнет писать по указателю целые байты, а массив вдруг упакован в биты?
Ладно, а если адрес этого массива будет передан например в DMA, и последний начнет писать в него байты, надеясь, что массив байтовый, а на деле компилятор слишком сумничал и упаковал в битовые поля?

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

53 минуты назад, Arlleex сказал:

Вообще массив выкинулся

 Никуда он не делся, он перешел в аргументы инструкций:

0x0800044A 2100      MOVS r1, #0x00
0x0800044C 2201      MOVS r2, #0x01

Я об этом писал ранее. Переместите этот массив из глобальной видимости в локальную вовнутрь функции, увидите возможно иное поведение. Конкретный вид зависит от включенной степени оптимизации.

Изменено пользователем Variant99

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


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

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

А если программист создаст указатель и где-то в коде неожиданно присвоит указателю адрес этого массива...

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

Цитата

Никуда он не делся, он перешел в аргументы инструкций:

Нет, именно выкинулся.

Цитата

Переместите этот массив из глобальной видимости в локальную вовнутрь функции, увидите иное поведение

Переместил и результат, разумеется, такой же.

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


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

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

А если программист создаст указатель и где-то в коде неожиданно присвоит указателю адрес этого массива, да еще не явно, а в результате вычислений, да еще и не отслеживаемых на этапе компиляции, и начнет писать по указателю целые байты, а массив вдруг упакован в биты?
Ладно, а если адрес этого массива будет передан например в DMA

Передан куда и откуда? зачем??? Высасываете из пальца.

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

 

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

Я об этом писал ранее. Переместите этот массив из глобальной видимости в локальную вовнутрь функции, увидите возможно иное поведение. Конкретный вид зависит от включенной степени оптимизации.

и что? Вы похоже не поняли смысл того примера.... :unknw:

 

PS: И вам вместе с тем программистом советую изучить назначение спецификатора volatile.

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


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

Что такое volatile я узнал еще раньше вас 🙂

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

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

если погроммист творит такое, то не программист он

Та ну? Приведите пример, почему.

А как быть с обычной таблицей с индексом, получаемым в результате обработки внешних (для компилятора) данных. Например, индекс  получается в результате приема значения UART, и по этому индексу в таблице помещается адрес того самого массива. Компилятор не может отследить, какой именно индекс будет выбран. 

Изменено пользователем Variant99

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


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

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

Что такое volatile я узнал еще раньше вас 🙂

Это сомнительно, иначе не писали бы ерунду про DMA и "вычислений, да еще и не отслеживаемых на этапе компиляции".

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

поясните подробнее с практическими примерами, будьте так любезны.

Научитесь всё-таки внимательнее читать посты:

2 часа назад, jcxz сказал:

А что если компилятор оказался настолько умнее погроммиста,

 

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

А как быть с обычной таблицей с индексом, получаемым в результате обработки внешних (для компилятора) данных. Например, индекс  получается в результате приема значения UART, и по этому индексу в таблице помещается адрес того самого массива.

С какого перепугу обращение по индексу вдруг стало "вычислениями не отслеживаемыми на этапе компиляции"? Адрес таблицы используется, значит компилятор знает, что обращение идёт к этой таблице. 

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

Компилятор не может отследить, какой именно индекс будет выбран. 

и что с того? Ему и не нужно знать какой индекс. Он возьмёт младшие три бита индекса как номер бита байта, а старшие биты - индекс упакованного байта.

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


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

Смешались люди, кони :))) Похоже, вы сами запутались в том, что изначально писали :))) В следующий раз лучше дважды подумайте, один раз напишите. А то, видимо, вы не очень то понимаете, что именно отслеживает компилятор при компиляции, а что выполняет микроконтроллер в процессе работы. 

Нет, не пишите тут много, просто в следующий раз вначале дважды подумайте. Океюшки? :)))

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


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

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

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

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

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

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

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

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

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

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