kan35 7 16 марта Опубликовано 16 марта · Жалоба Доброго дня всем! Пробую уменьшить расход стеков, компилятор у меня с очень низкими возможностями оптимизации, потому вот такой вопрос: Нужно считать несколько раз регистр, но само значение не нужно. Сейчас я завожу переменную и читаю в неё. unsigned char byte; byte = RCREG4; byte = RCREG4; byte = RCREG4; Но это же бессмысленно, как записать в Си чтение в никуда? Спасибо всем. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 141 16 марта Опубликовано 16 марта · Жалоба RCREG4; 2 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tonyk_av 44 16 марта Опубликовано 16 марта · Жалоба ( void )RCREG4: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kan35 7 16 марта Опубликовано 16 марта · Жалоба Благодарю, господа! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kan35 7 16 марта Опубликовано 16 марта · Жалоба Заменил unsigned char byte; byte = RCREG4; byte = RCREG4; byte = RCREG4; на (void)RCREG4; (void)RCREG4; (void)RCREG4; и по результату работы кода вижу, что он уже не делает вычитку из регистра. Компилятор C18 к сожалению не знаю как можно посмотреть дизассемблер этого куска кода... Есть ли еще что-нибудь более жестко регламентирующее, чтобы он не удалял эти строки из работы? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 16 марта Опубликовано 16 марта · Жалоба 4 минуты назад, kan35 сказал: Есть ли еще что-нибудь более жестко регламентирующее, чтобы он не удалял эти строки из работы? Есть. volatile при описании регистров. И писать нужно всё-таки: { тип i = RCREG4; } { тип i = RCREG4; } { тип i = RCREG4; } { тип i = RCREG4; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mitya1698 18 16 марта Опубликовано 16 марта · Жалоба ASM команой считать в какой-нибудт регистр Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kan35 7 16 марта Опубликовано 16 марта · Жалоба Регистр объявлен так: extern volatile far unsigned char RCREG4; не хотелось бы делать { тип i = RCREG4; } (у меня на самом деле оно примерно так и есть) Хочу, чтобы переменная в стеке не появлялась совсем. Просто поясню зачем мне это нужно: сейчас занялся высвобождением памяти, контролируя глубину стеков всех задач, таким образом, спасая один байт в обработчике прерываний я могу убавить стеки в 6ти задачах на 1, то есть по сути высвободится 6 байт. 13 minutes ago, mitya1698 said: ASM команой считать в какой-нибудт регистр у меня такая мысль тоже была, но есть нюанс - в какой регистр свободен в этот момент... Я конечно применяю, совсем простые инструкции, типа: void vApplicationIdleHook( void ) { _asm sleep _endasm } А вот с регистрами уже просадка... плохо понимаю архитекктуру выходного кода, да и архитектуру процессора тоже плохо осознаю 🙂 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 241 16 марта Опубликовано 16 марта · Жалоба 59 минут назад, kan35 сказал: не хотелось бы делать { тип i = RCREG4; } Почему? Это самый правильный вариант. 59 минут назад, kan35 сказал: Хочу, чтобы переменная в стеке не появлялась совсем. Просто поясню зачем мне это нужно: сейчас занялся высвобождением памяти, контролируя глубину стеков всех задач, таким образом, спасая один байт в обработчике прерываний я могу убавить стеки в 6ти задачах на 1, то есть по сути высвободится 6 байт. Во-первых: Где будет переменная (на стеке или ещё где-то) - зависит исключительно от компилятора. Нормальный компилятор для процессора с РОН-ами и на простом коде при включённой оптимизации должен расположить i в регистре. Не знаю какой у вас компилятор и процессор, разговор о конях в вакууме. Во-вторых: В вашем случае лучше подумать о переключении стека для ISR. Это даст значительно бОльший эффект. Как это сделать - зависит от многого. И от типа процессора и от наличия вложенности прерываний и т.п. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 50 16 марта Опубликовано 16 марта · Жалоба 2 часа назад, kan35 сказал: Хочу, чтобы переменная в стеке не появлялась совсем. Объявите ее глобальной. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tonyk_av 44 16 марта Опубликовано 16 марта · Жалоба 1 hour ago, jcxz said: Это самый правильный вариант. Это совсем не правильный вариант Запись ( void )RCREG4; _явно_ говорит компилятору и читающему код человеку о необходимости прочитать, но не сохранять прочитанное значение. Не просто так синтаксис языка разрешает такую конструкцию. 2 hours ago, jcxz said: И писать нужно всё-таки: { тип i = RCREG4; } { тип i = RCREG4; } { тип i = RCREG4; } { тип i = RCREG4; } А вот это начинает выглядеть как шарада для читающего. 3 hours ago, kan35 said: и по результату работы кода вижу, что он уже не делает вычитку из регистра. Компилятор C18 к сожалению не знаю как можно посмотреть дизассемблер этого куска кода... Какой компилятор? И какие опции оптимизации включены? P. S. GCC чётко по-стандарту разруливает вашу проблему. Главное- это не забыть про volatile. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gerber 8 16 марта Опубликовано 16 марта · Жалоба 22 минуты назад, tonyk_av сказал: P. S. GCC чётко по-стандарту разруливает вашу проблему. Главное- это не забыть про volatile. И ещё надо убедиться, что volatile относится не к указателю, а к переменной, на которую он указывает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 183 16 марта Опубликовано 16 марта · Жалоба Вообще все эти RCREG4; или (void)RCREG4; или через вызов фиктивной функции - сугубо на усмотрение конкретного компилятора И языка программирования. Си-шный стандарт сразу говорит, что понятие "доступа" в отношении к volatile-объектам отдается на усмотрение реализации: ISO/IEC 9899:201x: Цитата 6.7.3 Type qualifiers 7 ... What constitutes an access to an object that has volatile-qualified type is implementation-defined. Открыл референс на свой компайлер и читаю: Цитата A.1.12 Qualifiers Describes implementation-defined aspects of the Arm C compiler and C library relating to qualifiers, as required by the ISO C standard. What constitutes an access to an object that has volatile-qualified type (6.7.3). Modifications of an object that has a volatile qualified type constitutes an access to that object. Value computation of an lvalue expression with a volatile qualified type constitutes an access to the corresponding object, even when the value is discarded. В Си строчка RCREG4; является выражением и это выражение должно оцениваться компилятором. А оценка невозможна без доступа. А вот в C++ доступ к volatile в этом отношении несколько другой: он вполне вправе считать, что такое выражение не имеет смысла, о чем может выкинуть варнинг "Expression has no effect". Так что все несколько запутано и нужно проверять конкретно "у себя". А еще ссылка по теме, кому интересно: https://embeddedgurus.com/stack-overflow/2010/03/reading-a-register-for-its-side-effects-in-c-and-c/. Тут подверждается, что даже "правильная" для конкретного языка C/C++ конструкция - не гарантия. 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kan35 7 16 марта Опубликовано 16 марта · Жалоба Я там выше писал, компилятор - С18, для pic18. ANSI 89. И спасибо всем за комментарии Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vov4ick 39 16 марта Опубликовано 16 марта · Жалоба Ещё можно попробовать if (RCREG4); 1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться