3630 registros
0 hoje
14 nesta semana
4 neste mês|
Sex 19 Jun 2009 14:29 |
|
|
Instrução AND
Há 5 modos diferentes de se ANDar dois números:
Ou seja: variável1 db ? variável2 dw ? and cl, dh and al, variável1 and variável2, si and dl, 0C2h and variável1, 01001011b Observe que as constantes estão em notação hexadecimal e binária, as únicas aceitas por que são o único meio de expressar números bit a bit. É claro que a notação hexadecimal precisa ser convertida em 4 dígitos binários. AND retorna 1 quando ambos os operandos forem 1, senão retorna zero, conforme a tabela abaixo:
Pode-se verificar se um registrador está zerado utilizando a instrução AND, como em and ecx,ecx. Caso algum bit em ecx estiver setado (valor 1), este mesmo bit estará setado no resultado e a flag zero (ZF) estará zerada (valor falso). Se não houver bits setados, o resultado também não terá bits setados e a flag zero (ZF) recebe o valor 1. Nenhum bit será alterado e ecx mantém o seu valor original. Este é o modo padrão de se checar valores zerados. Uma alternativa para este teste é usando a instrução TEST. Também é possível testar uma variável com uma constante (fazer AND em duas variáveis dá erro!). No caso de and variável1, 11111111b testa-se todos os bits da variável1 com bits setados. Se algum bit da variável1 estiver setado, aparece setado no resultado e ZF = 0; se todos estiverem zerados, continuam zerados no resultado e ZF = 1. O valor da variável1, em ambos os casos, não é alterado. AND também é utilizado em máscaras. Caso se queira testar o bit na posição 0 do registrador ecx, podemos utilizar a instrução and ecx, 00000001b. O estado deste bit (setado ou zerado) será transportado para o resultado enquanto todos os outros serão zerados. Instrução CMP
A fonte pode ser um registrador, um endereço de memória ou um valor. O destino pode ser um registrador ou um endereço de memória. Exemplos: cmp eax, variável1 cmp variável2, TRUE Instrução DEC
Exemplos: dec eax dec variável1 Instrução INC
Exemplos: inc eax inc variável1 Instruções de saltoApenas os principais tipos de salto (jump) estão na tabela abaixo:
Instrução MOV
A instrução MOV transfere (MOVe) o conteúdo da fonte para o destino. Ao se executar a transferência, o conteúdo da fonte fica preservado e o conteúdo do destino é substituído pelo conteúdo da fonte. Instruções NEG e NOTNOT é uma operação lógica e NEG é uma operação aritmética. Ambas são descritas em conjunto para que as diferenças fiquem claras. NOT alterna o valor de cada bit individual: 1 -> 0 0 -> 1
NEG subtrai o operando destino de 0 e retorna o resultado a este mesmo destino. O efeito é um complemento de dois do operando. O operando também pode ser um byte ou um word. NEG nega o valor do registrador ou da variável numa operação COM sinal. NEG executa (0 - número), ou seja: neg eax neg variável1 é o mesmo que (0 - EAX) e (0 - variável1) respectivamente. NEG atualiza as flags da mesma maneira que (0 - número). Se o operando for 0 (zero), a flag de carry (CF) é zerada. Em todos os outros casos, a CF é setada para 1. Instrução OR
OR retorna 0 quando ambos os operandos forem 0, senão retorna 1, conforme a tabela abaixo:
OR é usado para ativar bits específicos. No exemplo a seguir, apenas o bit da posição 7 é ativado e os restantes não sofrem alteração: or dl, 10000000b ; ativa o bit da posição 7 (as posições dos 8 bits são de 0 a 7, em ordem inversa) OR também pode ser utilizado para checar se um registrador está zerado ou não porque o resultado atualiza o estado da flag de zero (ZF). Por exemplo: or ebx, ebx ; ebx é igual a zero ? jz ... Instrução POP
O destino pode ser um registrador ou um endereço de memória. A pilha é uma área de memória que armazena dados temporariamente. O registrador SP (stack pointer) sempre contém o endereço da localização que corresponde ao topo da pilha. O princípio de funcionamento da pilha é "último a entrar - primeiro a sair". A pilha é utilizada principalmente pelas instruções push, pop, call e return. Instrução PUSH
A fonte pode ser um registrador, um endereço de memória ou um valor literal. A pilha é uma área de memória que armazena dados temporariamente. O registrador SP (stack pointer) sempre contém o endereço da localização que corresponde ao topo da pilha. O princípio de funcionamento da pilha é "último a entrar - primeiro a sair". A pilha é utilizada principalmente pelas instruções push, pop, call e return. Instruções REP, REPE e REPNE
REPE e REPZ (repeat if zero / repetir se zero) têm o mesmo efeito. O mesmo acontece com REPNE e REPNZ (repeat if not zero / repetir se diferente de zero). Instrução SCAS
As formas permitidas são: scasb scasw scas BYTE PTR ES:[DI] scas WORD PTR ES:[DI] Instrução SHL
O destino pode ser um registro ou um endereço de memória. As "vezes" podem ser valores ou CL.
Instrução SHR
O destino pode ser um registro ou um endereço de memória. As "vezes" podem ser valores ou CL.
Instrução SUB
Ambos os operandos podem ser bytes ou words e ambos também podem ser números binários com ou sem sinal. Instrução TEST
Esta instrução é uma variação da instrução AND. TEST faz exatamente o mesmo que AND, apenas descarta os resultados obtidos. Não modifica o destino. Isto significa que pode checar coisas específicas sem alterar os dados. Em outras palavras, TEST faz um AND lógico em seus dois operandos e atualiza as flags sem modificar o destino e a fonte. test ebx,ebx ; EBX é zero ? jz ... ; se sim, então salta Para otimizar a velocidade, quando comparar um valor num registrador com 0, use o comando TEST. Use TEST quando for comparar o resultado de um comando lógico AND com uma constante imediata se o registrador utilizado for EAX. Também pode ser usado para testar se determinado valor é zero (exemplo: test ebx,ebx seta a flag zero (ZF) se EBX for zero). TEST é muito útil para examinar o status de bits individuais. Por exemplo, o snippet abaixo passará o controle para UM_CINCO_OFF se ambos os bits 1 e 5 do registrador AL estiverem zerados (lembre-se de que os bits são numerados de 0 a 7 em ordem inversa). O status de todos os outros bits será ignorado. test al,00100010b ; filtre os bits 1 e 5 jz UM_CINCO_OFF ; se o bit 1 ou o bit 5 estiverem setados, o resultado ; será diferente de zero ... AMBOS_NAO_OFF: ... UM_CINCO_OFF: ... TEST oferece as mesmas possibilidades que AND: variável1 db ? variável2 dw ? test cl, dh test al, variável1 test variável2, si test dl, 0C2h test variável1, 01001011b Um bom exemplo é para a placa de vídeo. Em modo texto, a tela tem 80 x 25 pixels, perfazendo 2000 células. Cada célula possui um byte de caracter e um byte de atributos. O byte do caracter é o valor ASCII do mesmo. O byte de atributos indica a cor do caracter, a cor de fundo, se o caracter está em alta ou baixa intensidade ou se está piscando. Um byte de atributos tem a seguinte aparência:
Os bits 0, 1 e 2 (RGB) indicam a cor do caracter. 2 é vermelho (Red), 1 é verde (Green) e 0 é azul (Blue). Os bits 4, 5 e 6 (RGB) contém a cor de fundo do caracter, onde 6 é vermelho (Red), 5 é verde (Green) e 4 é azul (Blue). O bit 3 indica alta intensidade e o bit 7 é piscante. Se o bit estiver setado (valor 1), o componente correspondente está ativado. Se o bit estiver zerado, o componente correspondente está desativado. A primeira coisa que chama a atenção é o quanto de memória é economizado pelo fato das informações estarem todas juntas. Claro que seria possível usar um byte para cada uma das características, mas a memória requerida seria de 8 x 2 000 bytes = 16 000 bytes. Se adicionarmos os 2 000 bytes referentes aos caracteres, o total já seria 18 000 bytes. Da forma explicada acima, obtém-se o mesmo resultado com apenas 4 000 bytes, ou seja, uma economia de 75%. Como há quatro telas (páginas) diferentes numa placa com cores, os totais seriam 72 000 (18 000 x 4) contra 16 000 (4 000 x 4). Imagine agora que um dos bytes de atributos esteja no registrador DL - pode-se achar quais os bits que estão setados, bastando para isto fazer um TEST DL com um padrão de bits específico. Se a flag zero (ZF) for setada, significa que o resultado é zero e que o bit estava zerado. test dl, 10000000b ; está piscando ? test dl, 00010000b ; tem azul no fundo ? test dl, 00000100b ; a cor do caracter é vermelho ? A flag zero (ZF) indica se o componente está ativo ou desativo. Esta flag não vai mostrar se a cor de fundo é azul, porque o vermelho e o verde do fundo também podem estar setados. Apenas um dos componentes pode ser testado em cada test. E lembre-se: TEST não altera os valores da fonte ou do destino, apenas atualiza as flags. MáscarasUsaremos o byte de atributos do monitor para exemplificar o uso de máscaras.
Os bits 0, 1 e 2 (RGB) indicam a cor do caracter. 2 é vermelho (Red), 1 é verde (Green) e 0 é azul (Blue). Os bits 4, 5 e 6 (RGB) contém a cor de fundo do caracter, onde 6 é vermelho (Red), 5 é verde (Green) e 4 é azul (Blue). O bit 3 indica alta intensidade e o bit 7 é piscante. Se o bit estiver setado (valor 1), o componente correspondente está ativado. Se o bit estiver zerado, o componente correspondente está desativado. Caso se queira ativar ou desativar determinados bits, sem alterar o valor dos outros, podemos lançar mão de uma máscara AND: and byte_do_video, 10001111b. Lembrando que a instrução AND retorna 1 apenas quando ambos os bits estiverem setados (tiverem valor 1), sabemos que neste caso os bits 4, 5 e 6 serão zerados enquanto que os outros permanecem inalterados. Como os bits zerados correspondem à cor de fundo, esta operação tornou a cor de fundo preta. Se quisermos definir a cor de fundo, precisamos de duas operações. A primeira, uma operação de máscara AND como descrito acima, para fazer a cor de fundo preta zerando os bits desejados sem modificar os restantes. A segunda, uma operação de máscara OR, para ativar os bits desejados sem alterar os restantes (cor de fundo azul): and byte_de_video, 10001111b or byte_de_video, 00010000b As constantes binárias utilizadas para fazer o AND e o OR são chamadas de máscaras. Estas constantes podem estar no formato binário ou hexadecimal. Por exemplo, and byte_de_video, 10001111b é o mesmo que and byte_de_video, 8Fh e or byte_de_video, 00010000b é o mesmo que or byte_de_vídeo, 10h. Reveja as instruções AND e OR caso ainda tenha alguma dúvida. Instrução XOR
XOR retorna 1 quando os operandos forem diferentes, senão retorna 0, conforme a tabela abaixo:
O OU-Exclusivo Lógico (XOR) significa que o resultado SÓ É VERDADEIRO SE AS CONDIÇÕES FOREM DIFERENTES. Falso e verdadeiro também podem indicar o estado de bits, portanto, podemos efetuar uma operação de OU-Exclusivo Lógico entre dois bits (como na tabela acima) ou numa sequência de bits. Tomemos como exemplo a operação 77 XOR 25. Como sabemos que a operação lógica XOR também é feita bit a bit, precisamos dos valores binários desses dois números para efetuar a operação: Observe que apenas nas posições onde os bits são diferentes o resultado possui bits com valor 1, portanto, 77 XOR 25 = 84. Um aspecto interessante da operação XOR é que ela é reversível: se fizermos um XOR do resultado com o primeiro operando, obtemos o valor do segundo operando. Da mesma forma, se fizermos um XOR do resultado com o segundo operando, o resultado é o primeiro operando. Outra característica é que, fazendo o XOR de um número com ele mesmo, o resultado sempre será zero. Faça os testes e verifique |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Última atualização ( Sáb, 20.06.2009 16:42 ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||