o que e 0xFF fazem?

Anding um inteiro com 0xFF deixa apenas o byte menos significativo. Por exemplo, para obter o primeiro byte em um short s, você pode escrever s & 0xFF. Isso é normalmente referido como”mascaramento”. Se byte1 for um único tipo de byte (como uint8_t) ou já tiver menos de 256 (e, como resultado, todos os zeros, exceto o byte menos significativo), não há necessidade de mascarar os bits mais altos, pois eles já são zero.

veja a resposta de tristopiaPatrick Schlüter abaixo quando você pode estar trabalhando com tipos assinados. Ao fazer operações bit a bit, recomendo trabalhar apenas com tipos não assinados.

se byte1 é um número inteiro de 8 bits tipo, então é inútil – se é mais do que 8 bits que será, essencialmente, dar-lhe os últimos 8 bits do valor:

 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 & 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 ------------------------------- 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1

O perigo da segunda expressão vem se o tipo de byte1 é char. Nesse caso, algumas implementações podem tê-lo signed char, o que resultará em extensão de sinal ao avaliar.

signed char byte1 = 0x80;signed char byte2 = 0x10;unsigned short value1 = ((byte2 << 8) | (byte1 & 0xFF));unsigned short value2 = ((byte2 << 8) | byte1);printf("value1=%hu %hx\n", value1, value1);printf("value2=%hu %hx\n", value2, value2);

irá imprimir

value1=4224 1080 rightvalue2=65408 ff80 wrong!!

eu tentei no gcc v3.4.6 no Solaris SPARC 64 bit e o resultado é o mesmo com byte1 e byte2 declarados como char.

TL;DR

o mascaramento é evitar a extensão implícita do sinal.

editar: verifiquei, é o mesmo comportamento em C++.

EDIT2: conforme solicitado explicação da extensão do sinal.A extensão de sinal é uma consequência da maneira como C avalia expressões. Existe uma regra em C chamada regra de promoção. C lançará implicitamente todos os tipos pequenos para int antes de fazer a avaliação. Vamos ver o que acontece com a nossa expressão:

unsigned short value2 = ((byte2 << 8) | byte1);

byte1 é uma variável contendo padrão de bits 0xFF. Se char for unsigned esse valor é interpretado como 255, se for signed é -128. Ao fazer o cálculo, C estenderá o valor para um tamanho int (16 ou 32 bits geralmente). Isso significa que se a variável for unsigned e mantermos o valor 255, o padrão de bits desse valor como int será 0x000000FF. Se for signed queremos o valor -128 Qual padrão de bits é 0xFFFFFFFF. O sinal foi estendido para o tamanho da tempory usada para fazer o cálculo.E assim oring o temporário produzirá o resultado errado.

na montagem x86 é feito com a instrução movsx (movzx para a extensão zero). Outras CPUs tinham outras instruções para isso (6809 tinha SEX).

Deixe uma resposta

O seu endereço de email não será publicado.