почему выбирают свой комплимент при записи в реестр - PullRequest
3 голосов
/ 23 января 2012

Каковы преимущества, например, написания первого утверждения по сравнению со вторым утверждением:

Первое утверждение:

ANCON1 = ~0x0C;

Второе утверждение:

ANCON1 = 0xF3;

Я вижу второй вариант как ясный выбор, потому что он более прямолинеен, чем первый. Зачем использовать One's Complement, когда так просто написать то, что мы хотим.

Ответы [ 5 ]

3 голосов
/ 23 января 2012

Бенуа в значительной степени сказал это. Один - это дополнение, все, кроме этих битов, другой - только эти биты.

something&=~3;

Часто означает, что вы сосредотачиваетесь на тех двух битах, где 0xFC - на других битах. ~ версия отображается прямо на немного понятной инструкции на некоторых платформах, что делает ее более удобной для автора, возможно, так. И версия ~ менее подвержена ошибкам и ошибкам, если вы измените размер переменной (не перемещая эти два бита), ваш код все еще работает, при использовании 0xFC код нарушается и должен касаться везде, где используется переменная. (использование #define для сокрытия константы ухудшает отладку. Возможно, будет лучше, если определение будет использовано повторно, но ущерб уже нанесен).

В конце концов, это стиль, как и

if(!(x&something) {

против

if((x&something)==0) {

против

if(x&something) ; else {

На уроке рисования или рисования вас, вероятно, научат фокусироваться на негативе, на фоне, рисовать не контур объекта, а контур того, что не является объектом.

В колледже (электротехника, по крайней мере, десятилетия назад, до появления компьютерной техники) нас поощряли мыслить с точки зрения негативной логики. Иногда утверждать означает положительную логику, иногда отрицательную логику и не думать только один путь. (то же самое относится и к утверждению «включено» или «включено» - положительное напряжение, VCC, «отключено» или «выключено» - заземление)

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

Так же просто «написать» 0xC, как 0xF3, если вам скажут, например, в устной форме, или в таблице указано, что биты [3: 2] - это что-то и то и то, когда ноль. Мозгу не составит труда обработать это как 0xC, чтобы обработать его как 0xF3, нужно найти больше информации о длине вещи, а затем обработать биты до и после, прежде чем достигнет 0xF3. Или вы сделали 0xF3 в своей голове из 0x0C, и вы могли просто использовать ~ 0x0C и сохранить шаг. Если есть диаграмма, показывающая все биты рядом с помеченными полями, то это означает, что стакан наполовину пуст или наполовину полон, вы и ваши глаза можете легко сфокусироваться на негативе и потянуть 0xF3 напрямую или сфокусироваться на 0x0C и затем инвертировать в получить 0xF3 или сосредоточиться на 0xF3 и придется инвертировать, чтобы получить 0x0C.

Два преимущества, одно из которых гораздо менее важно, чем другое, заключаются в том, что на нескольких процессорах оно напрямую связано с инструкцией, и оптимизатору не приходится работать усердно (микрооптимизация), а другое - это привычка избегать программных ошибок. Если вы использовали int несколько лет назад с 0xFFFFFFF3, а затем скомпилировали этот код сегодня без каких-либо модификаций для 64-битной машины, возможно, вы ошиблись. если этот метод обычно используется в коде, то есть много портирования. Если бы использовалось ~ 0xC, то этот код мог бы быть перенесен более плавно. Один подразумевает размер переменной, другой нет.

3 голосов
/ 23 января 2012

Я прочитал первый All but 00001100, а второй 11110011.Мне легче понять, какие биты НЕ установлены мысленно, потому что их меньше.

1 голос
/ 23 января 2012

Прежде всего, ~ означает побитовое дополнение.Не путайте это с дополнением, дополнение - это способ перевести шестнадцатеричный формат в целочисленный со знаком.

Что касается хорошей / плохой практики, оба ваших примера плохие, потому что они используют «магические числа»,Хороший способ написать тот же код:

#define MASK 0x0C

ANCON1 = ~MASK;

Поскольку MASK - это то, что имеет смысл, а 0xF3 - это случайное магическое число, вы должны использовать первое и затем инвертировать его.

Обратите внимание, что оператор ~, используемый для целочисленной константы, предварительно обрабатывается во время компиляции.Фактический машинный код будет выглядеть примерно так: LOADx $F3.

1 голос
/ 23 января 2012

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

Другое дело, если бы вы использовали переменную-для отрицания, а затем для записи переменной в регистр на большинстве микроконтроллеров использовали 2 команды, а для записи только переменной в регистр - 1.

0 голосов
/ 23 января 2012

Обычно это только вопрос стиля.Первый, x = ~y - это идиома, обычно используемая для обозначения установки всех битов в x, за исключением битов в y.

. Еще чаще используется вместе с &= оператор.Например, x &= ~y означает очистку битов в x, установленных в y.В этом случае его удобнее читать, например x &= ~0x40, а не x &= 0xFC.

...