Operações "booleanas" com bits
http://www.ic.unicamp.br/~celio/mc404-s2-2015/docs/bits-howto.html
ou (no Arm: instrução orr)
0 ou 0 = 0
0 ou 1 = 1
1 ou 0 = 1
1 ou 1 = 1
Para ligar (por em 1) um bit b qualquer:
1 ou b (0 ou b = b, ou seja, não altera o valor de b)
and (no Arm: instrução and)
0 and 0 = 0
0 and 1 = 0
1 and 0 = 0
1 and 1 = 1
Para desligar (por em 0) um bit b qualquer:
0 and b (1 and b = b, ou seja, não altera o valor de b)
Ou exclusivo (no Arm: instrução eor)
0 eor 0 = 0
0 eor 1 = 1
1 eor 0 = 1
1 eor 1 = 0
Para complementar um bit b qualquer:
1 eor b (0 eor b = b, ou seja, não altera o valor de b)
Regras "mnemônicas":
ou: ou 1 ou outro bit ligado = 1, ambos desligados =0
and: ambos ligados = 1 senão = 0
ou exclusivo: um ou outro mas não ambos ligados =1 senão 0
Quando usando as instruções citadas as operações atuam em paralelo
para cada bit dos operandos (registradores e/ou constantes utilizadas).
Quando alterando bits através de uma constante como operando, ela é usualmente
chamada de "máscara":
Exemplos:
desligar os 28 bits + significativos de r0 sem alterar os 4 menos significativos:
and r0, 0x0000000f (por economia pode ser escrito: and r0,0x0f)
ligar os 4 bits - significativos de r0 sem alterar os outros:
orr r0, 0x0000000f (por economia pode ser escrito: orr r0, 0x0f)
complementar todos os bits de r0
eor r0, 0xffffffff
É comum precisarmos de uma máscara para ligar o bit i de um registrador, (31 => i >=0).
O montador pode gerar facilmente esta máscara através da operação 1<<i que significa:
"desloque a constante 1 i bits para a esquerda".
Exemplo:
orr r0, r0, (1<<28) @ liga o bit 28 do registrador r0
para zerar um bit qualquer de de r0 usaremos a instrução bic (bit clear):
bic r0, r0, (1<<28) @ desliga o bit 28 do registrador r0
Mágicas com o "ou exclusivo"
O seguinte trecho de programa em C troca os valores de 2 variáveis a e b
sem usar uma variável temporária:
a = a ^ b;
b = a ^ b;
a = a ^ b;
Exercícios:
(i) usando a definição do ou exclusivo, prove a afirmação acima, lembrando
que a xor a = 0
(ii)supondo que r0 é a e r1 é b escreva as instruções em assembler que
correspondem aos 3 comandos acima (ou seja, troca o conteúdo de r0 com o de r1).
Um desafio:
As seguintes operações com bits são suportadas pela linguagem C
(a e b são números inteiros sem sinal de 32 bits):
a | b ou bit a bit de a e b
a & b and bit a bit de a e b
a ^ b ou exclusivo bit a bit de a e b
a << k deslocamento à esquerda de k bits de a (entram zeros nos k bits menos signifcativos)
a >> k deslocamento à direita de k bits de a (entram zeros nos k bits mais significativos)
Sejam a, b, k e nb variáveis, onde,
a é um valor inteiro sem sinal de 32 bits
b é um valor binário com até k bits, onde
k é um valor binário entre 1 e 32
nb é um valor binário entre 0 e 31 que representa um número de bit
O problema:
usando apenas as operações com bits descritas acima inserir a partir do bit nb de a
k bits da variável b sem alterar os outros bits de a.
(você pode usar variáveis temporárias e atribuições).
Dicas:
(i) Para simplificar a notação use -1 como sendo a constante com 32 bits 1 (ffffffff)
(ii) a especificação do problema requer a construção de uma "máscara" de 32 bits
onde os bits nb a nb+k-1 são 0 e todos os outros são 1;
(iii) ao fazer o "and" dessa máscara com o valor de a os bits nb a nb+k-1 de a são zerados
mas os outros não são alterados;
(iv)em seguida faça o "ou" de a com o valor b deslocado nb bits à esquerda
Simplificação: se k e nb forem constantes prefixadas (e não variáveis) fica bem
mais simples construir a máscara.
Por exemplo, se k=8 e nb=4 a máscara é: fffff00f (em hexadecimal)