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

Как в Си считать регистр процессора "в никуда"?

Доброго дня всем!

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

Нужно считать несколько раз регистр, но само значение не нужно. Сейчас я завожу переменную и читаю в неё.

unsigned char byte;
byte = RCREG4;
byte = RCREG4;
byte = RCREG4;

Но это же бессмысленно, как записать в Си чтение в никуда?

Спасибо всем.

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


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

Заменил

            unsigned char byte;
            byte = RCREG4;
            byte = RCREG4;
            byte = RCREG4;

на

(void)RCREG4;
(void)RCREG4;
(void)RCREG4;

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

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

Есть ли еще что-нибудь более жестко регламентирующее, чтобы он не удалял эти строки из работы?

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


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

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

Есть ли еще что-нибудь более жестко регламентирующее, чтобы он не удалял эти строки из работы?

Есть. volatile при описании регистров.

И писать нужно всё-таки:

{ тип i = RCREG4; }
{ тип i = RCREG4; }
{ тип i = RCREG4; }
{ тип i = RCREG4; }

 

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


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

Регистр объявлен так:

extern volatile far  unsigned char       RCREG4;

не хотелось бы делать

{ тип i = RCREG4; }

(у меня на самом деле оно примерно так и есть)

Хочу, чтобы переменная в стеке не появлялась совсем. Просто поясню зачем мне это нужно: сейчас занялся высвобождением памяти, контролируя глубину стеков всех задач, таким образом, спасая один байт в обработчике прерываний я могу убавить стеки в 6ти задачах на 1, то есть по сути высвободится 6 байт.

13 minutes ago, mitya1698 said:

ASM команой считать в какой-нибудт регистр

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

Я конечно применяю, совсем простые инструкции, типа:

void vApplicationIdleHook( void )
{
    _asm
        sleep
    _endasm
}

А вот с регистрами уже просадка... плохо понимаю архитекктуру выходного кода, да и архитектуру процессора тоже плохо осознаю 🙂

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


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

59 минут назад, kan35 сказал:

не хотелось бы делать

{ тип i = RCREG4; }

Почему? Это самый правильный вариант.

59 минут назад, kan35 сказал:

Хочу, чтобы переменная в стеке не появлялась совсем. Просто поясню зачем мне это нужно: сейчас занялся высвобождением памяти, контролируя глубину стеков всех задач, таким образом, спасая один байт в обработчике прерываний я могу убавить стеки в 6ти задачах на 1, то есть по сути высвободится 6 байт.

Во-первых: Где будет переменная (на стеке или ещё где-то) - зависит исключительно от компилятора. Нормальный компилятор для процессора с РОН-ами и на простом коде при включённой оптимизации должен расположить i в регистре. Не знаю какой у вас компилятор и процессор, разговор о конях в вакууме.

Во-вторых: В вашем случае лучше подумать о переключении стека для ISR. Это даст значительно бОльший эффект. Как это сделать - зависит от многого. И от типа процессора и от наличия вложенности прерываний и т.п.

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


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

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

Хочу, чтобы переменная в стеке не появлялась совсем.

Объявите ее глобальной.

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


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

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.

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


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

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

P. S. GCC чётко по-стандарту разруливает вашу проблему. Главное- это не забыть про volatile.

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

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


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

Вообще все эти 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++ конструкция - не гарантия.

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


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

Я там выше писал, компилятор  - С18, для pic18. ANSI 89. 
И спасибо всем за комментарии 

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


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

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

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

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

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

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

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

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

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

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