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

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

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

Смешались люди, кони :)))

Что именно у вас там смешалось - в том сами разбирайтесь. Но думаю всем здесь будет интересно услышать: Зачем и куда именно требуется передавать адрес внутренней переменной программы через DMA?

4 часа назад, Variant99 сказал:

Ладно, а если адрес этого массива будет передан например в DMA

Раскроете секрет? Как единственный здесь понимающий "что именно отслеживает компилятор при компиляции, а что выполняет микроконтроллер в процессе работы"...  :mosking:

Уж просветите нас тёмных, непонимающих...  :punish:

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


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

И Variant99, и jcxz по своему правы. Очень подробно и правильно расписан механизм инициализации памяти еще на первой странице, но такое поведение возможно, если не баловаться выше -O0. При других уровнях оптимизации компилятор может перепахать код до неузнаваемости.

Например, такой исходник (обработчик энкодера опросом порта)

		enc_state = (enc_state >> 2) | ((GPIOA->IDR >> (13 - 2)) & 0x0C);
		switch(enc_state)
		{
			case 0b0010:
			case 0b1011:
			case 0b1101:
			case 0b0100:
				enc_count--;
				delay = 0;
				break;
			case 0b0001:
			case 0b0111:
			case 0b1110:
			case 0b1000:
				enc_count++;
				delay = 0;
				break;
		}

Превращается в такой набор инструкций:

 80033be:	f04f 4390 	mov.w	r3, #1207959552			; r3 = 0x48000000
 80033c2:	8a1a      	ldrh	r2, [r3, #16] 			; r2 = GPIOA->IDR
 80033c4:	4b2b      	ldr	r3, [pc, #172]				; ([8003474] = 0x20000024 = .bss)
 80033c6:	0ad2      	lsrs	r2, r2, #11				; r2 = (GPIOA->IDR >> (13 - 2))
 80033c8:	6a99      	ldr	r1, [r3, #40]				; r1 = enc_state
 80033ca:	f002 020c 	and.w	r2, r2, #12				; r2 = (GPIOA->IDR >> (13 - 2))& 0x0C
 80033ce:	ea42 02a1 	orr.w	r2, r2, r1, asr #2		; r2 = (enc_state >> 2) | ((GPIOA->IDR >> (13 - 2)) & 0x0C)
 80033d2:	2a0e      	cmp	r2, #14
 80033d4:	629a      	str	r2, [r3, #40]				; enc_state = r2
 80033d6:	d80a      	bhi.n	80033ee 				; end switch
 80033d8:	2101      	movs	r1, #1
 80033da:	fa01 f202 	lsl.w	r2, r1, r2				; r2 = (1 << enc_state)
 80033de:	f642 0114 	movw	r1, #10260				; 0x2814 = 0b0010100000010100 = (1 << 0b0010) | (1 << 0b0100) | (1 << 0b1011) | (1 << 0b1101)
 80033e2:	4011      	ands	r1, r2
 80033e4:	d127      	bne.n	8003436					; dec_enc_count
 80033e6:	f244 1082 	movw	r0, #16770				; 0x4182 = 0b0100000110000010 = (1 << 0b0001) | (1 << 0b0111) | (1 << 0b1000) | (1 << 0b1110)
 80033ea:	4202      	tst	r2, r0
 80033ec:	d129      	bne.n	8003442 				; inc_enc_count

Компилятор красиво оптимизировал switch - я бы так не сообразил.

При этом исходник для меня остался читабельным, а код стал эффективным.

PS. А по теме - патчить бинарник = зло!

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


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

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

Про остальное, jcxz где-то чето недопонял, из-за этого всё поперепутал, перевернул и завязал узлом, и сам потерялся. Распутывать его узлы чето нет желания. Не понял он - ну и фик с ним, не понял так не понял, какая разница.

 

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

А по теме - патчить бинарник = зло!

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

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

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


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

В 15.12.2022 в 02:42, Variant99 сказал:

"оптимизация выключена".

упс, я как-то это уточнение не заметил :))

В 15.12.2022 в 02:42, Variant99 сказал:

Про остальное, jcxz

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

В 15.12.2022 в 02:42, Variant99 сказал:

Как-то было дело

был бы у вас исходник, уверен, что правили бы его, а не бинарник.

 

Тут мельком было упоминание про дизассемблер (тоже хочу пару байт найти и поправить).

Кто что использует для cortex-m ? radare2 ?

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


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

3 hours ago, Variant99 said:

Как-то было дело - снимал в бинарнике защиту от проверки серийного номера.

В том-то и дело, что правка бинарника возникает от безысходности, т.е. когда другого варианта получить желаемое поведение программы просто нет или оно слишком дорого. Допускаю, что так можно делать, снимая защиту с какого-нибудь блока и превратить Ладу Калину в Mercedes Benz))))) Но вот делать такое для клиента в серийном, скажем, приборе - быть ССЗБ (сам себе злобный Буратина). Правильнее, конечно, написать ПО с нуля, если нет исходников. Потому, что клиенту может понадобиться ещё что-то и каждый раз лазить в бинарник и искать там смещения - то ещё удовольствие. Но ещё более правильно найти ответ на вопрос: а почему нет исходников? И почему болезнь/уволнение одного программиста заставляют заниматься таким сомнительным бизнесом??? Это же вообще, ИМХО, недопустимая ситуация. Исходники же не у него на "айфоне" хранятся. Они должны быть на корпоративном сервере (git) или, на крайний случай, на его рабочей (не домашней) машине в офисе. В противном случае, приходиться бороться с последствиями, тогда как устранить причину может оказаться и дешевле и быстрее и просто эффективнее.

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


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

4 часа назад, Variant99 сказал:

Я как раз и исходил из того, что топикстартер написал: "оптимизация выключена". Поэтому никакие оптимизации компилятор не применяет.

Если исходить из "оптимизация выключена" в 1-м сообщении ТС, то значит у ТС есть исходники проекта. И он их может перекомпилить. А значит его попытки ковыряния в уже скомпилённом образе - вообще непонятно - на кой??? Он не смог разобраться в исходниках болезного коллеги? или что?

Если есть исходники - пусть их правит, а не занимается ерундой в скомпилённом образе.

А если у него нет исходников, а только готовый результирующий образ, то откуда тогда известно что "оптимизация выключена"? :shok:

 

4 часа назад, Variant99 сказал:

Про остальное, jcxz где-то чето недопонял, из-за этого всё поперепутал, перевернул и завязал узлом, и сам потерялся. Распутывать его узлы чето нет желания.

Так мы получим или нет ответ на вопрос:

7 часов назад, jcxz сказал:

Зачем и куда именно требуется передавать адрес внутренней переменной программы через DMA?

Или сливаетесь? На конкретный вопрос ответьте, не надо крутиться как уж на сковороде!

4 часа назад, Variant99 сказал:

Не понял он - ну и фик с ним, не понял так не понял, какая разница.

Т.е. - всё что вы выше навалили - это просто был наброс на вентилятор??? Так надо понимать?

4 часа назад, adnega сказал:

упс, я как-то это уточнение не заметил :))

Из этого уточнения следует, что у ТС есть исходники проекта. И тогда вообще непонятно зачем он развёл весь сыр-бор.

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


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

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

На конкретный вопрос ответьте, не надо крутиться как уж на сковороде!

Ну если вы невнимательно читали или что-то недопоняли, то поясню, что я имел ввиду "адрес массива передать в DMA channel memory address register в качестве адреса назначения для работы DMA". Теперь понятно? Я это и написал, просто вы прочли "по диагонали", а дальше запутались и не поняли.

По всему остальному, топикстартер написал, что доступа к сишным исходникам у него нету, но он вроде как видел эти исходники и почему-то уверен именно в том, что массив был задан как uint8_t array[180] = { 1, 0 и так далее }. Где и в какой области видимости был массив задан, как использовался, для чего предназначен, каков размер бинарника, топикстартер не уточнял. 

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


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

22 minutes ago, Variant99 said:

"адрес массива передать в DMA channel memory address register в качестве адреса назначения для работы DMA". Теперь понятно?

А откуда возьмёт программист адрес массива? Разве не оператором &? В этом случае компилятор будет точно знать, что идёт обращение к массиву. Я не знаю как точно взаимодействуют компилятор и линкер в современных условиях, но наверняка есть способ оградить при необходимости массив от различных оптимизаций и оставить его как он есть.

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


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

On 12/15/2022 at 8:08 AM, haker_fox said:

А откуда возьмёт программист адрес массива? Разве не оператором &? 

Нет.

Оператором & можно взять адрес элемента массива.

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


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

On 12/15/2022 at 9:20 AM, jcxz said:

Из этого уточнения следует, что у ТС есть исходники проекта. И тогда вообще непонятно зачем он развёл весь сыр-бор.

Исходника нету. Про то, что оптимизация у него отключена знаю, т.к. вместе сидели за его компом и я видел это в настройках проекта.

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


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

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

Ну если вы невнимательно читали или что-то недопоняли, то поясню, что я имел ввиду "адрес массива передать в DMA channel memory address register в качестве адреса назначения для работы DMA". Теперь понятно?

Если именно "адрес масива использовать как адрес назначения DMA", то такой массив следует объявлять с квалификатором volatile. И тогда компилятор не будет производить никаких оптимизаций над данными в нём. И тогда ваш наброс на вентилятор по поводу DMA - совершенно не к месту. И именно поэтому вам был дан совет насчёт изучения назначения volatile.

Это вам теперь надеюсь понятно? 

 

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

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

Я это и написал, просто вы прочли "по диагонали", а дальше запутались и не поняли.

Ваши выражения очень косноязычны. И понятны видимо только вам.

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


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

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

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

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

Ваши выражения очень косноязычны

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

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


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

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

Исходника нету. Про то, что оптимизация у него отключена знаю, т.к. вместе сидели за его компом и я видел это в настройках проекта.

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

Если же оптимизация была отключена временно, на время отладки, то её состояние при вашем сидении рядом не говорит ровно ни о чём. Позже он отладил код и включил оптимизцию на максимум.

Так что: в 1-м случае нужно просто переписывать исходники по-новой; а во 2-м - тоже нет смысла ковырять и что-то править в готовом образе.

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


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

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

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

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

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


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

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

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

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

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

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

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

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

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

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