Jump to content
    

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

Товарищи,

имеется программа для STM32 на Си. Компилятор Keil MDK-ARM, оптимизация отключена.

В программе имеется такой массив нулей и единичек.

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 байт всего};

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

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

Share this post


Link to post
Share on other sites

1 hour ago, TOG said:

И кто этим занимается ?

1. Можно прочитать в документации на компилятор. Обычно там расписан процесс запуска с момента старта процессора до входа в функцию main().

2. Можно пройтись отладчиком с вектора сброса до main().

3. Выше уважаемый @x893 уже ответил.

1 hour ago, TOG said:

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

Может быть формат поиска текста не совпал?

Share this post


Link to post
Share on other sites

1 minute ago, haker_fox said:

Может быть формат поиска текста не совпал?

Там в кодированном виде. Примерно - тип инициализации, значение, длина (разные есть). Можно Отладчиком/IDA/гидрой посмотреть.

Share this post


Link to post
Share on other sites

В зависимости от того, где этот массив создан - локально внутри функции или глобально (в том числе и статически локально).

Вот они, глобально созданные 5 элементов (20 байт) и локально созданные и инициализованные 7 элементов (28 байт):
1986522133_2022-12-14113155.thumb.png.621dfc09d292c2f80cb953d5798f211e.png

указаны адреса, по которым лежат эти значения. Это же можно увидеть в файле листинга .list, ищите в нем вверху табличку и строки .rodata и .data, там указаны те же сведения, что и на скрине выше. 
Для globalArray они находятся во флеше начиная от адреса 0x08000258 и копируются в SRAM начиная с адреса 0x20000000 перед запуском main(), и затем располагаются в SRAM. КРазмещением кода занимается секция .data скрипта загрузчика .ld, и непосредственно код копирования CopyDataInit в файле startup. Если глобально создать массив, но не обращаться к нему в тексте кода, то он не будет включен в компиляцию.
Для localArray инициализующие значения хранятся во флеше по указанному адресу 0x08000234, и копируются в SRAM в стек функции в момент вызова функции, в которой этот массив определен. Адрес размещения в SRAM в общем случае неизвестен и зависит от того, в каком месте программы вызывается эта фкнуция. Вот код этого копирования:

451000477_2022-12-14113831.png.1b6f3911a6bc256d9f785738fb79c8ac.png

А вот кстати они в скомпилированном бинарнике по указанным адресам и сидят (в hex-виде, не в десятичном!):

918913995_2022-12-14115717.png.1a7de6d3c055869a7bdd78b661615e3f.png

Смотреть бинарник или hex конечно нужно через утилиту просмотра hex или bin, например ST-Link. В hex-файле в чистом виде там конечно ничего не поймете, ибо он закодирован.

Edited by Variant99

Share this post


Link to post
Share on other sites

On 12/14/2022 at 8:39 AM, Variant99 said:

Смотреть бинарник или hex конечно нужно через утилиту просмотра hex или bin, например ST-Link. В hex-файле в чистом виде там конечно ничего не поймете, ибо он закодирован.

Чем и кем он закодирован ?

HEX файл это обычный тестовый файл. Открывается любым блокнотом. С очень простым форматом.

 

On 12/14/2022 at 8:10 AM, haker_fox said:

Может быть формат поиска текста не совпал?

Видимо да.

On 12/14/2022 at 6:51 AM, TOG said:

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

Вот так ваша последовательность выглядит в бинарном файле 

image.thumb.png.54b97069c5200cc316cc0b1ac2e41510.png

Вот так последовательность выглядит в HEX файле

Quote

:10CFB000208240420024F400D5AF020801010100A4
:10CFC000000001000100010101000000010001005A
:10CFD0000100010088000020000000007403002010

 

On 12/14/2022 at 6:51 AM, TOG said:

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

 

Выше ответили.

 

А вообще, не понятно для чего это вам нужно. Какая разница куда там чего компилятор разместил.

Share this post


Link to post
Share on other sites

2 hours ago, Arlleex said:

static const uint8_t data[] = ...

Именно! RW-данные могут быть и скомпрессированы, например.

Share this post


Link to post
Share on other sites

38 минут назад, dimka76 сказал:

Чем и кем он закодирован ?

Авторами формата HEX. Внедрены дополнительные символы в начале и в конце строки, они могут путать.

15 минут назад, aaarrr сказал:

static const uint8_t data[]

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

const int globalArray[5] = {1000, 20000, 300000, 4000, 5};

    int a = globalArray[0];
 8000152:	f44f 737a 	mov.w	r3, #1000	; 0x3e8
 8000156:	60fb      	str	r3, [r7, #12]
	int b = globalArray[1];
 8000158:	f644 6320 	movw	r3, #20000	; 0x4e20
 800015c:	60bb      	str	r3, [r7, #8]
	int c = globalArray[2];
 800015e:	4b06      	ldr	r3, [pc, #24]	; (8000178 <main+0x2c>)
 8000160:	607b      	str	r3, [r7, #4]

Квалификатор static указывает только на область видимости для работы компилятора.

Share this post


Link to post
Share on other sites

2 hours ago, Arlleex said:

static const uint8_t data[] = ...

Возможно, что автор хочет эти данные менять по ходу пьесы) Как я понял, ему интересно, где находятся его данные для инициализации:blum:

Share this post


Link to post
Share on other sites

При любом раскладе, инициализующие данные находятся во флеше, где ж им еще быть то. Для случая глобального массива с квалификатором const массив в явном виде исчезает и превращается в нечто подобное:

8000152:	f44f 737a 	mov.w	r3, #1000	; 0x3e8
...
8000158:	f644 6320 	movw	r3, #20000	; 0x4e20
...
800015e:	4b06      	ldr	r3, [pc, #24]	; (8000178 <main+0x2c>)
...
8000178:	000493e0 	.word	0x000493e0
...
8000162:	2305      	movs	r3, #5

Однако, локальный const массив может быть помещен снова в виде явного массива во флеш. 
Кароче, всё сильно зависит от того, как именно и где именно объявлен массив и какая именно оптимизация включена.

Edited by Variant99

Share this post


Link to post
Share on other sites

On 12/14/2022 at 11:23 AM, haker_fox said:

Возможно, что автор хочет эти данные менять по ходу пьесы) Как я понял, ему интересно, где находятся его данные для инициализации:blum:

У автора не static const, а простой массив, который в ОЗУ располагается. 

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

Share this post


Link to post
Share on other sites

On 12/14/2022 at 1:23 PM, haker_fox said:

Возможно, что автор хочет эти данные менять по ходу пьесы) Как я понял, ему интересно, где находятся его данные для инициализации:blum:

Сотрудник, который сделал эту программу на больничном. У меня есть только МК с прошивкой. У него в программе на Си я точно видел, что объявлен массив был просто uint8_t data[] = {1,1,1,0,0,1 ..... всего 180 байт).

Сейчас хотел немного подправить массив в прошивке, а найти его не могу.

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

То есть так просто тут изменения не внесешь.

 F100RE.thumb.png.3188c2b917a6c6a559c594d4ae80a31a.png

Edited by TOG

Share this post


Link to post
Share on other sites

10 minutes ago, TOG said:

То есть так просто тут изменения не внесешь.

Уже написал - данные сжаты конкретным алгоритмом.

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

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

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

Share this post


Link to post
Share on other sites

42 minutes ago, TOG said:

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

Его состояние позволяет Вам дать исходник?

42 minutes ago, TOG said:

Сейчас хотел немного подправить массив в прошивке

Так делать опасно: прошивка может быть защищена контрольной суммой или линкер склеил одинаковые секции. Вы поправите данные массива, даже если их и найдёте, а программа перестанет работать. Т.к. эти данные нужны были другому участку кода.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...