Compare el valor del registro usando AND lógico (&) y ==

// Hardware sets a RIS interrupt status bit    
if(GPIO_PORTE_RIS_R & 0x10)   
{
   // Software acknowledges the flag and clears the read-only RIS bit by setting ICR
   GPIO_PORTE_ICR_R = 0x10;  
   // something useful 
}

El código anterior debe explicarse por sí mismo: el hardware marca un bit de registro, el software lo borra. Lo que no entiendo es por qué el código usa GPIO_PORTE_RIS_R & 0x10para comparar el valor del registro en lugar de GPIO_PORTE_RIS_R == 0x10.

==la operación probablemente equivaldría a un CMPseguido de un BEQo BNEen ensamblaje, o puede ser SUBScon una rama marcando el Zbit (Cero). De cualquier manera, el uso ==es sencillo e intuitivo: no tengo que convertir valores en binarios para predecir un resultado.

Pero con &y decir si GPIO_PORTE_RIS_R = 0x20, ellógicoLa operación AND bit a bit entre 0x20 & 0x10o 0010.0000 & 0001.0000en binario dará como resultado 0000.0000 o un falso . E imagine si GPIO_PORTE_RIS_R = 0x30o 0011.0000en binario, la declaración de condición devolvería verdadero incluso si los dos operandos ( 0x30 & 0x10) no son iguales. Parece como si el &operador verificara si un registro contiene un valor (o viceversa, un registro es un subconjunto de un valor). Es confuso pensar o usar.

¿En qué situación debo usar &en lugar de ==y por qué? ¿Y hay una forma más sencilla de pensar en ello?

Una cosa más: en C, AND lógico es y &&AND bit a bit es &.

Respuestas (2)

Cuando escribe, if REG & 0x10está comprobando si el bit 4 del registro REGestá establecido.

Si el valor de REG es 0x30, entonces se establece el bit 4 y debe hacer lo que desea hacer cuando se establece el bit 4.

Si el valor del REG es 0x20, el bit 4 no está configurado, por lo que no debe hacer lo que desea cuando el bit 4 está configurado.

Y ese es exactamente el comportamiento que obtienes si escribes if REG & 0x10 {...}.

Lo que no entiendo es por qué el código usa GPIO_PORTE_RIS_R & 0x10para comparar el valor del registro en lugar de GPIO_PORTE_RIS_R == 0x10.

Si usó ==entonces si se configuró el bit 4, pero también se configuró algún otro bit, entonces no haría lo que quiera hacer cuando se configuró el bit 4.

Pero dado que desea hacer eso cuando el bit 4 está configurado independientemente de los otros bits configurados, entonces esto está mal.

Regla de oro:

  • Úselo &cuando le importen los bits individuales y solo esos bits.
  • Utilícelo ==cuando le interese el valor total de una variable.

Por supuesto, también puede usar &para comparar una variable completa con una máscara, y en ese caso es casi equivalente a ==. Except &devuelve cero o un valor distinto de cero, mientras que ==siempre devuelve 0o 1.


Diferencias avanzadas:
ambos operadores son equivalentes en lo que respecta al orden de evaluación; no se especifica. Son equivalentes cuando se trata de promociones de tipo implícito, excepto que el resultado de &es siempre del tipo de los operandos (promocionados), mientras que el resultado de ==es siempre int.

Ejemplo (computadora de 32 bits):

uint64_t a;
uint64_t b;
printf("%zu\n", sizeof (a & b));  // prints 8
printf("%zu\n", sizeof (a == b)); // prints 4
Para usuarios de C++: ==devuelve un bool.