2015-07-09 4 views
2

Прошло некоторое время с тех пор, как я запрограммировал C и выполнил любую маскировку.C Регистры маскировки бит

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

Например: $ 0x00AA всегда должен иметь формат 0b101XXX01, где X являются изменяемыми, а все остальное должно оставаться постоянным. В настоящее время функция принимает адрес и значение и просто устанавливает это значение для этого адреса. Мне нужно изменить его, так что, даже если функция передана в 0b11111111 для регистра $ 0x00AA, она должна быть установлена ​​в 0b10111101. Аналогично, для 0b00000000 - 0b10100001.

+0

Вы могут использовать побитовые операторы ('|', '&', '~') для этого, особенно для версий оператор-оператор ('| =', '& ='). – Medinoc

+0

Вы имеете в виду, что хотите побитовое И? – ace

+0

Вам необходимо определить, что переданный адрес является одним из ваших охраняемых адресов, и в этом случае перед его установкой применить маску к значению. Сколько у вас охраняемых адресов, и они используются в другом месте? – Quentin

ответ

2

Вы можете сначала замаскировать что-либо, кроме измененных битов с побитовым И, а затем добавить константные биты с побитовым ИЛИ.

void set_register(uint8_t value) { 
    const uint8_t MUTABLE_BITS = 0x1C; // 0b00011100 <- only mutable bits 
    const uint8_t CONSTANT_BITS = 0xA1; // 0b10100001 <- constant 1-bits 

    value &= MUTABLE_BITS; // remove any non-mutable bits 
    value |= CONSTANT_BITS; // add the constant bits 
    my_register = value; 
} 

Этот подход имеет сомнительную особенность жесткого кодирования значения постоянных битов (в соответствии с названием «постоянной»). Другой подход должен были бы установить только изменяемые биты и принимают значения для остальные из самого регистра (побитового И с комплементом изменяемых бит маски), например:

void set_register(uint8_t value) { 
    const uint8_t MUTABLE_BITS = 0x1C; // 0b00011100 <- only mutable bits 

    value &= MUTABLE_BITS; // remove any non-mutable bits 
    value |= my_register & ~MUTABLE_BITS; // take other bits from register 
    my_register = value; 
} 

(Что касается требования, чтобы сделать это для нескольких регистров с разными масками, я бы ожидал, что они будут достаточно ограниченными по количеству, которые вы можете просто установить по одному. Если вам действительно нужна функция, которая принимает указатель и значение, вы должны тогда проверить, что указатель против известные охраняемые адреса и получить соответствующую маску. Выбор для этого диапазона от if/else до switch для двоичного поиска на каком-либо хэш-карте.)

Смежные вопросы