As linguagens de baixo nível são divididas em duas categorias: primeira geração e segunda geração.
Primeira Geração
A linguagem de primeira geração, ou 1GL, é o código de máquina. É a única linguagem que um microprocessador pode entender nativamente. O código de máquina não pode ser escrito ou lido por um editor de texto, e portanto é raramente usado por uma pessoa diretamente.
Exemplos: 1 - instrução de adição dos computadores B-200, B-300 e B-500 da Burroughs Corporation:
O=Op Code M e N variaveis que definem os campos dos endereços AAA e BBB
AAA, BBB e CCC campos com os endereços dos operandos
Campo O M N AAA BBB CCC
Código: 1 2 3 100 200 300
Interpretação:
1.O - 1 Código da instrução de adição
2.M - 2 Quantidade de dígitos da parcela 1, em AAA
3.N - 3 Quantidade de dígitos da parcela 2, em BBB
4.AAA - 100 endereço da parcela 1
5.BBB - 200 endereço da parcela 2
6.CCC - 300 endereço onde deve ser armazenado o resultado da adição da parcela 1 com a parcela 2.
2 - uma das instruções de adição do microprocessador de sinal digital (DSP) TMS-320C54x da Texas Instruments:
0000000SIAAAAAAA
Interpretação:
0000000 - Código desta instrução de adição.
S - define qual dos dois acumuladores será usado: 0 acumulador "A", 1 acumulador "B" I - indica o modo de endereçamento: 0 é endereçamento direto, 1 indireto.
AAAAAAA - Address (endereço) Esta instrução soma um valor de 16 bits da memória (cujo endereço está no apontador) ao acumulador selecionado
Segunda Geração
A linguagem de segunda geração, ou 2GL, é a linguagem Assembly. É considerada de segunda geração pois embora não seja uma linguagem nativa do microprocessador, uma linguagem Assembly ainda deve compreender as características da arquitetura do microprocessador (como registradores e instruções).
Uma linguagem de montagem ou assembly é uma notação legível por humanos para o código de máquina que uma arquitectura de computador específica usa. A linguagem de máquina, que é um mero padrão de bits, torna-se legível pela substituição dos valores em bruto por símbolos chamados mnemônicos.
Por exemplo, enquanto um computador sabe o que a instrução-máquina IA-21 (10110000 01100001) faz, para os programadores é mais fácil recordar a representação equivalente em intruções mnemônicas MOV AL, 61h. Tal instrução ordena que o valor hexadecimal 61 (97, em decimal) seja movido para o registrador 'AL'.
Arquitetura
Ao contrário do que acontece nas linguagens de alto nível, existe (até certo ponto) uma correspondência de 1 para 1 entre a linguagem de montagem simples e a linguagem de máquina. Por isso a tradução do código de montagem em código de máquina não é chamada compilação, mas montagem. Consegue-se transformar a linguagem de montagem em linguagem de máquina recorrendo a um montador (também chamado assembler, originado do termo em inglês), e a transformação inversa faz-se recorrendo a um desmontador (também chamado disassembler, originado do termo em inglês).
Cada arquitectura de computador tem a sua própria linguagem de máquina e, portanto, sua própria linguagem de montagem. Essas linguagens de montagem diferem no número e tipo de operações que suportam. Também têm diferentes tamanhos e números de registos, e diferentes representações dos tipos de dados armazenados. Enquanto todos os computadores de utilização genérica são capazes de desempenhar essencialmente as mesmas funções, o modo como o fazem é diferente.
Além disso, podem existir conjuntos múltiplos de mnemónicas, ou sintaxes de linguagem de montagem, para um único conjunto de instruções. Nestes casos, o conjunto mais popular é aquele que é utilizado pelo fabricante na sua documentação.
A maioria dos processadores só consegue manipular os dados que estão em registradores e a linguagem de montagem facilita o trabalho direto com os registradores.
No mercado de PCs, dominado por processadores Intel e AMD, atualmente existem duas arquiteturas. Primeiro a IA32, criada pela Intel em 1985 e primeiramente utilizada pelo processadores i386 e segundo a IA32-EM64T (ou IA32-AMD64 ) criada em 2002 pela AMD (Mas também utilizada pela Intel hoje). O IA32 utiliza o grupo de instruções chamado x86, e o IA32-EM64T utiliza o grupo chamado x86-64. As duas arquiteturas usam numeros diferentes de registradores gerais e tamanho. Enquanto os registradores do x86 são 32 bits os da x86-64 são 64 bits.Aqui no nosso blog será tratado apenas dessas plataformas,ou seja, Intel.São as mais utilizadas, e se você compreender bem, poderá fazer o mesmo em qualquer outra plataforma.O que mudará serão as instruções, e os registradores, e modo de endereçamento.O raciocínio é o mesmo.
Essa foi apenas uma introdução, não ligue muito para o termo, com o tempo irão se clareando cada vez mais. Considere isso como os tópicos, que com o tempo precisará assimilar.
Estamos estudando um computador, certo?Computar significa armazenar. Trabalhar com informações, dados.Hoje esse conceito foi muito ampliado, mas tudo não passa, na parte técnica, de processamento de informações. Celulares, redes 3g, rádios, objetos eletrônicos são sistemas lógicos baseados em informações, e hoje , são cada vez mais digitais, e menos analógicos. Utilizam pacotes de dados que trafegam em suas redes. O ábaco(aquela plaquinha com bolinhas utilizados por orientas como forma de cálculo) é um computador de forma diminuta. Para trabalhar com dados, precisamos acima de tudo, de transformá-los em modelos que podem ser acessados por um determinado sistema. No nosso caso, utilizaremos o sistema binário e o sistema hexadecimal. Em sua infra-estrutura, o processador e um micro-controlador só reconhecem 0 e 1, quando o sistema é digital. Queria lembrar que para nós humanos seria muito tosco e difícil raciocinar em forma binária ou hexadecimal, por uma razão bem simples: Possuímos dez dedos. Portanto, nosso sistema de contagem só faz sentido quando transformamos numa forma decimal. E por aí vai. Um Opcode, é uma tradução em hexadecimal de nossa instrução, chamada mnemônica junto com os dados, que estamos trabalhando. É uma forma mais simples de compreender quantos bytes possui uma instrução e seu dado.Mas lembre-se, o processador ou micro-controlador só compreende o 0 e 1. Nós inserimos símbolos que sejam legíveis para nós.
Alguém pode perguntar, mas peraí....existe outra forma de número que não o decimal?sim.Os maias por exemplo, utilizavam um sistema com base 20, ou seja, diferente do nosso. Isso, provavelmente, porque contavam com os dedos dos pés e das mãos ao mesmo tempo. Todo sistema em qualquer base possui as mesmas características de matemática. Só que possui uma conotação diferente. Se nós tivéssemos só um dedo, provavelmente contaríamos de forma binária. Ou tem dedo, ou não tem. Por exemplo:
0+0=0 Se não temos dedos nenhum, é zero.
0+1=1 Se um dedo se soma com nenhum?Temos um dedo.
Idêntico ao sistema decimal, porém lembre-se da regra do vai um na soma:
Em decimal teríamos: 21+9=30.Vamos enxergar isso de forma mais clara:
21
09
---
30
Repare, 1 mais nove, dá dez.Então, se deve pensar assim, 0 e vai um.Certo?dois com um, dá três. Em binário é igual:
01
01
--
10
Ou seja: 1 mais 1, é 0 e vai um.Só temos dois números...lembre-se disso.1 mais zero é um.Isso, seria o equivalente em dois em binário.
Como vamos trabalhar com computação, iremos trabalhar muito com isso. É como o ábaco. Se você dissesse 12 para alguém calcular em ábaco, ele contaria as bolinhas equivalentes ao número doze em decimal, certo? E isso varia, de ábaco para ábaco. Há uns com cinco unidades e outros com dez unidades. A representação em cada um seria diferente, particular. Como no computador. Mas diferente do ábaco, letras também são representadas por binários no processador ou micro-controlador, e binário ou hexadecimal para nós.
Já se perguntou como você sabe a noção de quantidade de 345 em decimal? Nós sabemos que equivale a trezentos e quarenta e cinco. O algoritmo para se conhecer esse valor, nós aprendemos na alfabetização, quando a professora escrevia um quadro unidade, dezena, centena, milhar, lembra? Pois é, existe uma fórmula matemática para isso. Um número em determinada base, é a somatória de todos os seus dígitos, multiplicados por sua base, elevados a potência equivalente à sua posição.
Por exemplo, 345 equivale à duas posições contadas da direita para esquerda, incluindo o zero.
5= posição zero.
4=posição 1.
3=posição 2.
Agora, peque meu enunciado e aplique aqui:
3(dígito)*10(base)^2(esse acento equivale a potência.2,ou seja,posição dois conforme acima)+ 4(dígito)*10(base)^1(esse acento equivale a potência.1,ou seja,posição um conforme acima)+ 5(dígito)*10(base)^0(esse acento equivale a potência.0,ou seja,posição zero conforme acima),ou melhor resumido:3*10^2+4*10^1+5*10^0=345. Ou seja, 3 casas da centena mais 4 casas da dezena, mais 5 casas da unidade. E assim, com qualquer número, em qualquer base. Outro exemplo:

Obs.: Qualquer número na posição de zero é um, mesmo o zero, pois se trata das casas unitárias.

Sistema binário
Se trata do 0 e 1. Pode ser simbolizado também em sistema lógicos em idéias, ou seja, ligado/desligado, aceso/apagado, ou seja, qualquer idéia que tenha apenas duas posições. No sistema binário, temos base dois. Como no sistema deciam fica mais fácil entender número grandes colocando-se o ponto, por exemplo, 1.000.456.000, mais fácil do que 1000456000, também costuma-se separar os dígitos binários de quatro em quatro, para facilitar sua compreensão, exemplo:0101 0101 do que 01010101. Outra coisa importante de se conhecer é por convenção colocar a letra b após o número, exemplo:01010101b para conhecimento de que é binário.O número mais à direita é o número menos significativo, cada número à esquerda é um bit sucessivo:
Binário de oito bits: X7 X6 X5 X4 X3 X2 X1 X0
Binário de 16 bits: X15 X14 X13 X12 X11 X10 X9 X8 X7 X6 X5 X4 X3 X2 X1 X0
O bit zero é chamado menor ordem. O bit mais à esquerda é o de maior ordem.
Bit : É a menor representação de um dado no computador, ou seja, um zero ou um 1.
NIBBLE: São quatro bits, exemplo: 0101b
Byte: São oito bits. Exemplo:

Note que isso é um byte, mas se olhar melhor, verá um byte tendo dois nibbles o de maior valor e o de menor valor:
Como um byte são oito bits, temos 2^8 tipos de valores, ou seja: 254. Estes podem ser números naturais de 0 a 255, números inteiros com sinais que pode ser de -128 a +127.Ou um caractere ASCII/IBM.
Dois bytes equivalem a uma WORD, e duas palavras(WORD) equivalem a duas palavras(DWORD):
WORD

Byte menos significativo e o mais significativo(com quatro nibbles cada um):
DWORD

O grande problema do sistema binário é sua verbosidade. Para representar o valor decimal 202, de apenas três casas decimais, precisamos de oito casas binárias. É óbvio que com um conjunto de dez dígitos possíveis, o sistema decimal pode representar números de uma forma muito mais compacta do que o sistema binário, que possui um conjunto de apenas dois dígitos. Valores grandes precisam de uma infinidade de casas binárias, tornando o número praticamente inutilizável para os mortais comuns. Além disso, as conversões entre decimal e binário são um tanto trabalhosas. Para mal dos pecados, o computador só "pensa" em binário. Resolveu-se então partir para uma solução radical, ou seja, criar um sistema cuja base fosse a mesma do tipo mais usado nos computadores. Como já vimos, os tipos mais utilizados são o byte e o word. Um byte possui oito bits - então foi criado um sistema octal. Um word possui 16 bits - então foi criado o sistema hexadecimal.
O bit menos significativo num nibble (como em qualquer outro grupo) é o bit 0.
Na prática, os números binários são muito desajeitados para serem usados. É por isso que a maioria dos programadores utiliza o sistema de numeração hexadecimal. O sistema de numeração hexadecimal (também conhecido simplesmente como hexa) fornece notações muito mais compactas que o sistema binário e a conversão entre hexa e binário é bastante simples quando se usa a seguinte tabela:
Hexadecimal Binário Hexadecimal Binário
0 0000 8 1000
1 0001 9 1001
2 0010 A 1010
3 0011 B 1011
4 0100 C 1100
5 0101 D 1101
6 0110 E 1110
7 0111 F 1111
Cada dígito hexadecimal pode representar um dos dezesseis valores entre 0 e 15. Como só existem dez dígitos decimais, foi preciso inventar seis dígitos adicionais. Optou-se pelas letras de A a F. Alguns exemplos de números hexadecimais seriam 1234, CADA, BEEF, 0FAB, FADA, FEFE, FAFA, etc. Como vamos nos referir com frequência a números em várias notações, é bom por ordem na casa desde já. Nos textos serão usadas as seguintes convenções:
- Todos os valores numéricos, independente da sua base, começam com um dígito decimal.
- Todos os valores hexadecimais terminam com a letra "h".
- Todos os valores binários terminam com a letra "b".
- Todos os valores decimais terminam com o sufixo "d".
Quando queremos transformar um número qualquer binário ou decimal, devemos utilizar aquela fórmula antiga que escrevi acima, por exemplo (10100101b)2, lê-se na base dois:
Sistema Hexadecimal
Possui 16 dígitos: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F
Veremos uma tabela que a cada nibble, ou seja, a cada 4 bits poderemos ter um hexadecimal:
Exemplo:
A convenção é colocar a letra h no final do número, e o zero antes de qualquer letra,exemplo: 0E120h.
Agora, e se quiséssemos o contrário, ou seja, converter decimal em binário ou hexadecimal?Faremos assim, dividiremos o número pela base que queremos, pegando o quociente da primeira divisão e colocando como dividendo da próxima divisão e os restos serão os números dessa base.Faremos a divisão até termos zero.Exemplo:
39 (base 10) converter em hexadecimal (base 16):
Input= Divisor; Result = quociente; Remainder=Resto.
Portanto, o número 39d equivale a 27h, em hexadecimal.Outro exemplo 43868:
O resultado é 0AB5Ch.Se quisermos saber como o processador irá entender esse número basta transformá-lo em binário, utilizando a tabela de hexadecimal acima:

Então, o número 0AB5Ch hexadecimal é entendido assim pelo processador 1010101101011100b, ou seja, binário.
Operações Aritméticas com Binários e Hexadecimais
Devemos ter cuidado em não pensar nesses números como se fosse decimais, ou seja:
9h
+ 1h
----
Você pode achar que o resultado é 10h, mas não é.A resposta correta é 0Ah.Assim como 10h mais 1h não é 11h. E sim 0Fh.A melhor forma na prática é usar uma calculadora do Windows de forma fácil.rs.Se quiser ter trabalho, o jeito mais fácil é transformar o hexadecimal em binário calcular.Depois, transformar de novo usando a tabela e ver o resultado.Então, vejamos a melhor forma de calcular os binários:
Soma de Binários
0+0=0
0+1=1
1+0=1
1+1=10, ou seja 0 e vai 1* (para somar ao digito imediatamente à esquerda)
Para somar dois números binários, o procedimento é o seguinte:
Exemplo 1:
*
1100
+ 111
-----
= 10011
Explicando: Os números binários são base 2, ou seja, há apenas dois algarismos: 0 (zero) ou 1 (um). Na soma de 0 com 1 o total é 1. Quando se soma 1 com 1, o resultado é 2, mas como 2 em binário é 10, o resultado é 0 (zero) e passa-se o outro 1 para a "frente", ou seja, para ser somado com o próximo elemento, conforme assinalado pelo asterisco,como no exemplo acima.
Exemplo 2:
**
1100
+ 1111
-----
= 11011
Explicando: Nesse caso acima (exemplo 2), na quarta coluna da direita para a esquerda, nos deparamos com uma soma de 1 com 1 mais a soma do 1 ( * ) que veio da soma anterior. Quando temos esse caso (1 + 1 + 1), o resultado é 1 e passa-se o outro 1 para frente.
Obs.:É melhor memorizar esse vai um, ou vem um, pois posteriormente veremos suas funções quando estivermos programando.Mas antes, aprenda a soletrar, para depois aprender escrever.
Subtração de Binários
0-0=0
0-1=1 e vai 1* para ser subtraido no digito seguinte
1-0=1
1-1=0
Para subtrair dois números binários, o procedimento é o seguinte:
* ***
1101110
- 10111
-------
= 1010111
Explicando: Quando temos 0 menos 1, precisamos "pedir emprestado" do elemento vizinho. Esse empréstimo vem valendo 2 (dois), pelo fato de ser um número binário. Então, no caso da coluna 0 - 1 = 1, porque na verdade a operação feita foi 2 - 1 = 1. Esse processo se repete e o elemento que cedeu o "empréstimo" e valia 1 passa a valer 0. Os asteriscos marcam os elementos que "emprestaram" para seus vizinhos. Perceba, que, logicamente, quando o valor for zero, ele não pode "emprestar" para ninguém, então o "pedido" passa para o próximo elemento e esse zero recebe o valor de 1.
Multiplicação de Binários
A multiplicação entre binários é similar à realizada com números decimais. A única diferença está no momento de somar os termos resultantes da operação:
1 0 1 1
x 1 0 1 0
---------
0 0 0 0
+ 1 0 1 1
+ 0 0 0 0
+ 1 0 1 1
---------------
= 1 1 0 1 1 1 0
*
Perceba que na soma de 0 e 1 o resultado será 1, mas na soma de 1 com 1, ao invés do resultado ser 2, ele será 0 (zero) e passa-se o 1 para a próxima coluna, conforme assinalado pelo asterisco. Nota que se a soma passar de 2 dígitos, deve-se somar o número em binário correspondente ( ex. 7 = 1001, 6 = 1000, 5 = 101, 4 = 100, 3 =11).
1 1 1
x 1 1 1
---------
1 1 1
+ 1 1 1
+ 1 1 1
---------------
= 1 1 0 0 0 1
No caso, a terceira coluna a soma dá 4 (com mais um da anterior), que adiciona um "1" duas colunas depois (100).
Divisão de Binários
Essa operação também é similar àquela realizada entre números decimais:
110 __10__
- 100 11—010
- 10—00
Deve-se observar somente a regra para subtração entre binários. Nesse exemplo a divisão de 110 por 10 teve como resultado 11.
Código BCD 8421
O código BCD é um sistema de representação dos dígitos decimais desde 0 até 9 com um código binário de 4 bits. Esse código BCD usa o sistema de pesos posicionais 8421 do código binário puro. Exatamente como binário puro, pode-se converter os números BCD em seus equivalentes decimais simplesmente somando os pesos das posições de bits onde aparece 1.
somando os pesos das posições de bits onde aparece 1.
Decimal, Binário Puro e BCD
Observe, entretanto, que existem apenas dez códigos válidos. Os números binários de 4 bits representando os números decimais desde 10 até 15 são inválidos no sistema BCD. Para representar um número decimal em notação BCD substitue-se cada dígito decimal pelo código de 4 bits apropriados.
Por exemplo, o inteiro decimal 834 em BCD é 1000 0011 0100. Cada dígito decimal é representado pelo seu código BCD 8421 equivalente. Um espaço é deixado entre cada grupo de 4 bits para evitar confusão do formato BCD com o código binário puro. Este método de representação também se aplica as frações decimais.
Por exemplo, a fração decimal 0,764 é “0.0111 0110 0100” em BCD. Novamente, cada dígito decimal é representado pelo seu código equivalente 8421, com um espaço entre cada grupo.
Uma vantagem do código BCD é que as dez combinações do código BCD são fáceis de lembrar. Conforme se começa a trabalhar com números binários regularmente, os números BCD tornam-se tão fáceis e automáticos como números decimais. Por esta razão, por simples inspeção da representação BCD de um número decimal pode-se efetuar a conversão quase tão rápido como se já estivesse na forma decimal.
Como exemplo, converter o número BCD no seu equivalente decimal. 0110 0010 1000.1001 0101 0100 = 628,954
O código BCD simplifica a interface Homem-máquina, mas é menos eficiente que o código binário puro. Usam-se mais bits para representar um dado número decimal em BCD que em notação binária pura.
Por exemplo, o número decimal 83 é escrito como 1000 0011. Em código binário puro, usam-se apenas 7 bits para representar o número 83. Em BCD, usam-se 8 bits. O código BCD é ineficiente, pois, para cada bit numa palavra de dado, há usualmente alguma circuitaria digital associada. A circuitaria extra associada com o código BCD custa mais, aumenta a complexidade do equipamento e consome mais energia. Operações aritméticas com números BCD também consomem mais tempo e são mais complexas que aquelas com números binários puros. Com quatro bits de informação binária, você pode representar um total de 24 = 16 estados diferentes ou os números decimais equivalentes desde o 0 até o 15. No sistema BCD, seis destes estados (10-15) são desperdiçados.
Quando o sistema numérico BCD é usado, alguma eficiência é perdida, mas aumenta-se o entendimento entre o equipamento digital e o operador humano.
Conversão Binário para BCD
A conversão de decimal para BCD é simples e direta. Entretanto, a conversão de binário para BCD não é direta. Uma conversão intermediária deve ser realizada primeiro. Por exemplo, o número 1011.01 é convertido no seu equivalente BCD.
Primeiro o número binário é convertido para decimal. 1011.01 = (1x23)+(0x22)+(1x21)+(1x20)+(0x2-1)+(1x2-2) =8+0+2+1+0+0,25 = 11,2510
Então o resultado decimal é convertido para BCD. 11,2510 = 0001 0001.0010 0101
Para converter de BCD para binário, as operações anteriores são invertidas. Por exemplo, o número BCD 1001 0110.0110 0010 0101 é convertido no seu equivalente binário.
1. O número BCD é convertido para decimal. 1001 0110.0110 0010 0101 = 96,625
2. O resultado decimal é convertido para binário
Inteiro Resto Posição Fração Inteiro Posição
96 ÷ 2 = 48 0 -> LSB 0,625 x 2 = 1,25 = 0,25 1 <- MSB 48 ÷ 2 = 24 0 0,250 x 2 = 0,50 = 0,50 0 24 ÷ 2 = 12 0 0,500 x 2 = 1,00 = 0 0 <- LSB 12 ÷ 2 = 06 0 06 ÷ 2 = 03 0 03 ÷ 2 = 01 1 01 ÷ 2 = 00 1 <- MSB 9610 = 11000002 0,62510 = 0.101 96,62510 = 9610 + 0,62510= 1100000 + 0.101 = 1100000.101 Como o número decimal intermediário contém uma parte inteira e uma parte decimal, cada parte é convertida como visto anteriormente. A soma binária (inteiro mais fração) 1100000.101 é equivalente ao número BCD 1001 0110.0110 0010 0101. Vários códigos binários são chamados códigos alfanuméricos pois eles são usados para representar caracteres assim como números. Código ASCII O "American Standard Code for Information Interchange" comumente referido como ASCII – também chamado ASCII completo, ou ASCII estendido –, é uma forma especial de código binário que é largamente utilizado em microprocessadores e equipamentos de comunicação de dados. Um novo nome para este código que está se tornando popular é "American National Standard Code for Information" (ANSCII). Entretanto, utilizaremos o termo consagrado, ASCII. É um código binário que usado em transferência de dados entre microprocessadores e seus dispositivos periféricos, e em comunicação de dados por rádio e telefone. Com 7 bits pode-se representar um total de 27 = 128 caracteres diferentes. Estes caracteres compreendem números decimais de 0 até 9, letras maiúsculas e minúsculas do alfabeto, mais alguns outros caracteres especiais usados para pontuação e controle de dados! Sistema Octal é um sistema de numeração cuja base é 8, ou seja, utiliza 8 símbolos para a representação de quantidade. No ocidente, estes símbolos são os algarismos arábicos: 0 1 2 3 4 5 6 7 O octal foi muito utilizado em informática como uma alternativa mais compacta ao binário na programação em linguagem de máquina. Hoje, o sistema hexadecimal é mais utilizado como alternativa ao binário. Este sistema também é um sistema posicional e a posição de seus algarismos determinada em relação à vírgula decimal. Caso isso não ocorra, supõe-se implicitamente colocada à direita do número. A aritmética desse sistema é semelhante a dos sistemas decimal e binário, o motivo pelo qual não será apresentada. Exemplo: - Qual o número decimal representado pelo número octal 4701? Utilizar a forma que ensinei lá em cima. 4 x 8³ + 7 x 8² + 0 x 8¹ + 1 x 8° = = 2048 + 448 + 0 + 1 = 2497. Conversões de um sistema para outro Conversão Decimal – Octal Método de multiplicações sucessivas por 8 É utilizado para converter uma fração decimal para o sistema octal. Multiplica-se a fração decimal por 8, obtendo-se na parte inteira do resultado o primeiro dígito da fração octal resultante. O processo é repetido sucessivamente com a parte fracionária do resultado para obter os dígitos seguintes e termina quando a parte fracionária é nula ou inferior à medida de erro especificada. Exemplo: Converter a fração decimal 0.140625 em octal. 0.140625 x 8 = 1.125 0.125 x 8 = 1.0 Combinamos os dois métodos anteriores podemos converter para octal números decimais com parte inteira e fracionária Método de subtrair potências de 8 Outro método de conversão de números decimais para o sistema octal que serve para números com partes inteiras e fracionária é o de subtrair potências de 8. é semelhante ao estudado para a conversão decimal – binário e para a sua aplicação é necessária uma tabela de potências de 8. Conversão Octal – Decimal Existem vários métodos, sendo mais comumente utilizado o proveniente da maneira que sempre fazemos aqui no blog, em que se faz a conversão de forma direta através da fórmula. Exemplo: Converter o número octal 764 para o sistema decimal 764 (8) = 7 x 8² + 6 x 8¹ + 4 x 8° = 448 + 48 + 4 = 500 (10) Conversão Hexadécimal – Binário Quando existir necessidade de converter números hexadécimais em binários, deve-se separar cada dígito do número hexadécimal e substituí-lo pelo seu valor correspondente de binário. Exemplo: Converter o número hexadécimal 1572 em binário. Logo, 1 5 7 2 = 0001 0101 0111 0010 Conversão Binário – Octal Para converter um número binário em octal, executa-se o processo inverso ao anterior. Agrupam-se os dígitos binários de 3 em 3 do ponto decimal da esquerda para a direita, substituindo-se cada trio de dígitos binários pelo equivalente dígito octal. Por exemplo, a conversão do número binário 1010111100 em octal: 001 010 111 100 1 2 7 4 Assim, tem-se 1010111100bin = 1274oct Conversão Octal – Hexadecimal Para esta conversão é necessário executar um passo intermediário utilizando o sistema binário. Primeiramente converte-se o número octal em binário e depois converte-se o binário para o sistema hexadecimal, agrupando-se os dígitos de 4 em 4 e fazendo cada grupo corresponder a um dígito hexadecimal. Por, exemplo, a conversão o número octal 1057 em hexadecimal: Passagem ao binário: 1 0 5 7 001 000 101 111 Passagem ao hexadecimal: 0010 0010 1111 2 2 F Assim, tem-se 1057oct = 22Fhex Conversão Hexadecimal – Octal Esta conversão, assim com a anterior, exige um passo intermediário em que se utiliza o sistema binário. Converte-se o número hexadecimal em binário e este em octal. Exemplo: Converter o número hexadecimal 1F4 em octal. 1 F 4 0001 1111 0100 Conversão para octal 0 7 6 4 000 111 110 100 Tabela de valores
Operações Lógicas com Bits
Aqui muitos daqueles que já estudaram circuitos eletrônicos saberão do que estou falando.É a lógica Booleana.São lógicas direcionadas a decisões.Seria como verdadeiro ou falso.Sim ou não.Essa lógica é muito utilizada em algoritmo, ou seja, sequência em que se faz as coisas.Por exemplo, se fóssemos fazer um algoritmo(modo de se fazer um procedimento, com detalhes de como fazer) de tomar banho, entenderíamos muito bem essa lógica.
Entrar no banheiro-verificar chuveiro=ligado?sim ou não.Se sim, abrimos a torneira para a água sair;se não, acionamos o interruptor para energia esquentar...e por aí vai.Como você pode ver, praticamente qualquer coisa pode ser colocada em termos booleanos.Até mesmo instruções de programas, quando você não souber fazer um bom algoritmo de algo em funções avançadas, faça o básico.Planeje no papel como seria feito, e utilize lógica booleana.Dá mais tempo, mais trabalho, mas sempre nos tira de alguma fria...rs!Todo circuito integrado utiliza essa lógica.Se você olhar uma placa verá esses símbolos contornados nela.São utilizados até mesmo em sistemas analógicos.Aliás, uma boa diferença para quem ainda não distingue analógico de digital, seria no exemplo do chuveiro o seguinte, as respostas sim ou não seriam digitais ou binárias, e o quanto você abre de água para chegar na temperatura certa ou ideal seria analógico.
Na matemática e na ciência da computação, as álgebras booleanas (também conhecida como "Álgebra de Boole") são estruturas algébricas que "capturam a essência" das operações lógicas E, OU e NÃO, bem como das operações da teoria de conjuntos soma, produto e complemento. Ela também é o fundamento da matemática computacional, baseada em números binários.
Receberam o nome de George Boole, matemático inglês, que foi o primeiro a defini-las como parte de um sistema de lógica em meados do século XIX. Mais especificamente, a álgebra booleana foi uma tentativa de utilizar técnicas algébricas para lidar com expressões no cálculo proposicional. Hoje, as álgebras booleanas têm muitas aplicações na electrônica. Foram pela primeira vez aplicadas a interruptores por Claude Shannon, no século XX.
Os operadores da álgebra booleana podem ser representados de várias formas. É frequente serem simplesmente escritos como E, OU ou NÃO (são mais comuns os seus equivalentes em inglês: AND, OR e NOT). Na descrição de circuitos também podem ser utilizados NAND (NOT AND), NOR (NOT OR) e XOR (OR exclusivo). Os matemáticos usam com frequência + para OU e . para E (visto que sob alguns aspectos estas operações são análogas à adição e multiplicação noutras estruturas algébricas) e representam NÃO com uma linha traçada sobre a expressão que está a ser negada.
Combinando binários e AND:
0 and 0 = 0
0 and 1 = 0
1 and 0 = 0
1 and 1 = 1
Tabela verdade AND:

Combinando OR :
0 or 0 = 0
0 or 1 = 1
1 or 0 = 1
1 or 1 = 1

Combinando XOR(OR-exclusivo):
0 xor 0 = 0
0 xor 1 = 1
1 xor 0 = 1
1 xor 1 = 0

Combinando NOT:
NOT 0 = 1
NOT 1 = 0

AND, OR e XOR são funções diádicas (precisam de dois operandos) e NOT é monádica. Por exemplo:
1 AND 1 = 1
0 OR 0 = 0
1 XOR 0 = 1
NOT 1 = 0
A base dos sistemas de computadores digitais modernos são os circuitos lógicos. Para poder entender como estes sistemas funcionam é preciso ter algum conhecimento da lógica digital e da álgebra booleana. Estes assuntos são muito extensos, geralmente temas de livrões inteiros. Neste capítulo vamos apenas dar uma olhada no feijão com arroz, apenas o suficiente para poder trabalhar com Assembly. A lógica booleana é a base dos sistemas binários. Usando um sistema de equações booleanas é possível representar qualquer algoritmo ou qualquer circuito eletrônico do computador. Este capítulo será uma breve introdução à álgebra booleana. Analisaremos tabelas lógicas, representação canônica, funções booleanas, simplificação de funções booleanas, desenho lógico, circuitos combinados e sequenciais e equivalência de hardware e software. A seção que trata da minimização (otimização) de funções lógicas usa Diagramas Veitch ou Diagramas de Karnaugh. As técnicas de otimização utilizadas reduzem o número de termos numa função booleana. É preciso ressaltar que muitos consideram estas técnicas de otimização obsoletas porque a redução do número de termos numa equação não tem mais a importância que lhe era atribuída tempos atrás. Usaremos o método de diagramas como exemplo de otimização, não como uma técnica a ser empregada regularmente. Se você se interessa por projetos de circuitos e otimização, vai precisar consultar outros textos para encontrar técnicas melhores.
Apesar deste capítulo tratar basicamente de hardware, lembre-se de que muitos dos conceitos se referem a equações booleanas (funções lógicas). Alguns exercícios de programação, que serão apresentados em outros capítulos, vão exigir este conhecimento.
Álgebra booleana
Colocarei um tópico apenas sobre operações booleanas e lógica booleana, por se tratar de um assunto complexo,e necessitar de especial atenção para ser compreensível!
Operações lógicas com Números Binários e Strings de Bits
Como foi visto, as funções lógicas funcionam apenas com operandos de bit único. Uma vez que o 80x86 usa grupos de 8, 16, 32 ou 64 bits, é preciso ampliar a definição destas funções para poder lidar com mais de dois bits. As funções lógicas do 80x86 operam na base do bit a bit, ou seja, tratam os bits da posição 0, depois os bits da posição 1 e assim sucessivamente. É como se fosse uma cadeia de operações. Por exemplo, se quisermos realizar uma operação AND com os números binários 1011 0101 e 1110 1110, faríamos a operação coluna a coluna:
1011 0101 AND
1110 1110
-----------
1010 0100
O resultado desta operação foi "ligar" os bits onde os dois são 1. Os bits restantes foram
zerados. Se quisermos garantir que os bits de 4 a 7 do primeiro operando sejam zerados e que os bits 0 a 3 fiquem inalterados, basta fazer um AND com 0000 1111. Observe:
1011 0101 AND
0000 1111
-----------
0000 0101
Se quisermos inverter o quinto bit, basta fazer um XOR com 0010 0000. O bit (ou os bits) que quisermos inverter, mandamos ligado. Os bits zerados não alteram os bits do primeiro operando. Assim, se quisermos inverter os bits 0 a 3, basta fazer um XOR com 0000 1111.
1011 0101 XOR
0000 1111
-----------
1011 1010
E o que acontece quando usamos um OR com 0000 1111? Os bits 0 não alteram os bits do primeiro operando e os bits 1 forçam os bits para 1. É um método excelente para ligar bits na (ou nas) posições desejadas.
1011 0101 OR
0000 1111
-----------
1011 1111
Este método é conhecido como máscara. Através de uma máscara de AND é possível zerar bits. Com uma máscara XOR é possível inverter bits e, através de uma máscara OR é possível ligar bits. Basta conhecer as funções e saber lidar com os bits. Quando temos números hexadecimais, o melhor é transformá-los em binário e depois aplicar as funções lógicas.
Sinal::
Até agora tratamos os números binários como valores sem sinal. Mas como se faz para
representar números negativos no sistema binário? É aí que entra o sistema de numeração do complemento de dois. Vamos lá.
Números com e sem sinal
Os números, no computador, não podem ser infinitos pelo simples fato de que a quantidade de bits disponível para expressá-los é restrita (8, 16, 32, ou qualquer quantidade que nunca será grande demais :smile: ). Com um número fixo de bits, o valor máximo também é fixo. Por exemplo, com 8 bits podemos obter no máximo o valor 256. Se quisermos expressar números negativos, teremos que dividir estas 256 possibilidades, metade para os positivos e metade para os negativos. Isto diminui o valor máximo, porém aumenta o valor mínimo. Se a divisão for bem feita, podemos obter -128 a 0 e 0 a 127. O mesmo raciocínio pode ser usado para 16 bits, 32bits, etc. Como regra geral, com n bits podemos representar valores com sinal entre -2(n-1) e 2(n-1)-1
Muito bem, já sabemos que podemos dividir o espaço dos valores numéricos oferecido pelos bits, mas ainda não sabemos como representar os valores negativos usando os bits. O microprocessador 80x86 usa a notação de complemento de dois. Neste sistema, o bit mais significativo é que sinaliza se o número é positivo ou negativo: se for 0, o número é positivo; se for 1, o número é negativo. Veja os exemplos para 16 bits:
8000h é negativo => 1000 0000 0000 0000
100h é positivo => 0000 0001 0000 0000
7FFFh é positivo => 0111 1111 1111 1111
FFFFh é negativo => 1111 1111 1111 1111

Se o bit O.A. for zero, então o número é positivo e é armazenado como um valor binário
padrão. Se o bit O.A. for um, então o número é negativo e é armazenado na forma de
complemento de dois. Para converter um número positivo para negativo use o seguinte
algoritmo:
- 1. Inverta todos os bits do número com uma operação lógica NOT.
- 2. Adicione 1 ao resultado.
No exemplo a seguir faremos a conversão de +5 para -5 usando o complemento de dois com apenas 8 bits:
Primeira linha é cinco em binário;
Segunda linha inverter todos os bits;
Adicionar 1 para obter o resultado.
Se repetirmos a operação com o valor encontrado para -5, voltamos a obter o valor original:
Primeira linha o complemento de dois para -5;
Segunda linha inverter todos os bits;
Adicionar 1 para obter o resultado +5.
Agora observe o que acontece com o hexadecimal 8000h, o menor número negativo com sinal (-32.768):
hexa 8000h
binário 1000 0000 0000 0000
(8000h) inverter bits
0111 1111 1111 1111 (7FFFh) somar 1
1000 0000 0000 0000 (8000h) ???
Invertendo 8000h obtemos 7FFFh e, somando 1, voltamos para 8000h. Tem alguma coisa errada pois -(-32768) não pode ser igual a -32768! O que ocorre é que, com 16 bits, não é possível obter o inteiro positivo +32768. Se tentarmos realizar o complemento de dois com o menor número negativo, o processador 80x86 vai dar erro de overflow na aritmética com sinal.
Talvez você esteja pensando que usar o bit mais significativo como flag de sinal e manter o número original fosse uma solução mais lógica. Por exemplo, 0101 seria +5 e 1101 seria -5. Acontece que esta operação depende do hardware. Para o processador, a negação (ou complemento, ou inversão) dos bits é fácil e rápida de ser realizada. Para o programdor, não é preciso realizá-la bit a bit pois o 80x86 possui a instrução NEG que trata todos os bits.
As operações com números negativos não são problemas. Imagine a operação de soma com os números +5 e -5, sendo que o -5 foi obtido com o sistema de complemento de dois:
1 1111 1111 5d
0000 0101 -5d
+ 1111 1011
------------
1 0000 0000
Os dígitos em vermelho são os famosos "vai um", que acontecem quando somamos dois bits de valor 1. O bit em azul é o bit que excedeu o comprimento de oito bits, chamado de carry (excedente). Se ignorarmos o carry, o resultado está absolutamente correto, pois 5 + (-5) = 0. É exatamente assim que o processador opera. Não custa repetir que os dados representados por um conjunto de bits dependem inteiramente do contexto. Os oito bits do valor binário 11000000b podem representar um caracter ASCII, o valor decimal sem sinal 192, o valor decimal com sinal -64, etc. Como programador, é sua a responsabilidade de usar os dados de forma consistente.
Extensão com Sinal e Extensão com Zeros
Como os inteiros no formato de complemento de dois têm um comprimento fixo, surge um pequeno problema. O que acontece quando for preciso transformar um valor de complemento de dois de 8 bits num valor de 16 bits? Este problema, e seu oposto (a transformação de um valor de 16 bits num de 8 bits), pode ser resolvido através das operações de extensão e contração com sinal. O 80x86 trabalha com valores de comprimento fixo, mesmo quando estiver processando números binários sem sinal. A extensão com zeros permite converter pequenos valores sem sinal em valores maiores sem sinal. Vamos a um exemplo considerando o valor -64. O valor de complemento de dois para este número é 0C0h. O equivalente de 16 bits deste número é 0FFC0h. Agora considere o valor +64. As versões de 8 e de 16 bits deste valor são 40h e 0040h. A diferença entre os números de 8 e de 16 bits com sinal pode ser definida com a seguinte regra: "Se o número for negativo, o byte mais significativo do número de 16 bits contém 0FFh; se o número for positivo, o byte mais significativo do número de 16 bits é zero".
Para fazer a extensão com sinal de um valor com qualquer número de bits para um número maior de bits, basta copiar o bit de sinal para todos os bits adicionais. Por exemplo, para ampliar um número de 8 bits com sinal para um número de 16 bits com sinal, só é preciso copiar o bit 7 do número de oito bits para os bits de 8 a 15 do número de 16 bits. Para ampliar um número de 16 bits para um número de double word (32 bits), simplesmente copie o bit 15 para os bits de 16 a 31 do double word.
A extensão com sinal é necessária quando manipulamos valores com sinal de comprimentos diferentes. É comum precisarmos somar uma quantidade em byte com uma quantidade em word. Neste caso, antes de efetuar a operação, será preciso transformar a quantidade byte numa quantidade word. Outras operações, em particular a multiplicação e a divisão, podem necessitar uma extensão com sinal para 32 bits. É óbvio que não é necessário fazer a extensão com sinal para valores sem sinal.
São exemplos de extensão com sinal:

Para ampliar números sem sinal faz-se a extensão com zeros, um processo muito simples de zerar os bytes adicionais. Veja abaixo:

A contração com sinal, ou seja, converter um valor com determinado número de bits para um valor idêntico com um número menor de bits é um processo um pouco mais complicado. A extensão com sinal sempre é possível, já a contração com sinal nem sempre o é. Por exemplo, o valor decimal -448, representado como hexadecimal de 16 bits, é 0FE40h. Neste caso, é impossível obter este valor com apenas 8 bits, ou seja, a contração com sinal não é possível pois o valor original seria perdido. Aliás, este é um exemplo de overflow que pode ocorrer numa conversão impossível.
Para avaliar se é possível realizar uma contração com sinal é preciso analisar o(s) byte(s) mais significativos que deverão ser descartados: todos precisam conter zero ou 0FFh. Se forem encontrados quaisquer outros valores, não será possível fazer uma contração sem overflow. Além disso, o bit mais significativo do valor resultante precisa coincidir com cada bit removido do número. Veja os exemplos:

Deslocamentos e Rotação
Outro conjunto de operações lógicas que podem ser aplicadas em strings de bits são o
deslocamento (shift) e a rotação (rotate). As duas categorias ainda podem ser subdivididas em deslocamento para a esquerda (left shift), deslocamento para a direita (right shift), rotação para a esquerda (left rotate) e rotação para a direita (right rotate). Estas operações se revelaram extremamente úteis para os programadores da linguagem Assembly.
Exemplo de um deslocamento para esquerda, A operação de deslocamento para a esquerda move uma posição para a esquerda cada um dos bits de uma string de bits (veja ao lado). O bit zero é deslocado para a posição 1, o da posição 1 para a posição 2, etc. Surgem naturalmente duas perguntas: "O que vai para o bit zero?" e "Para onde vai o bit 7?" Bem, isto depende do contexto. Nós colocaremos um bit zero na posição zero e bit sete "cai fora" nesta operação.

Observe que deslocar o valor para a esquerda é o mesmo que multiplicá-lo pela sua base (ou radix). Por exemplo, deslocar um número decimal para a esquerda em uma posição
(adicionando um zero à direita do número) o multiplica por 10 (a sua base):
1234 SHL 1 = 12340 (SHL 1 = shift esquerda 1 posição)
Como a base de um número binário é dois, o deslocamento em uma posição para a esquerda multiplica-o por 2. Se deslocarmos um valor binário duas vezes para a esquerda, ele é multiplicado duas vezes por 2, ou seja, é multiplicado por 4. Se o deslocarmos três vezes, será multiplicado por 8 (2*2*2). Como regra, se deslocarmos um valor binário para a esquerda n vezes, isto o multiplicará por 2n (ou 2 elevado a n).
O deslocamento para direita funciona do mesmo jeito, só que no sentido oposto.Bit sete para o seis, o seis para o cinco, o cinco para o quatro....No deslocamento para direita movemos um zero para o bit 7, o zero será o bit carry-out. Como o deslocamento para a esquerda equivale a uma multiplicação pela base, não é de se admirar que um deslocamento para a direita equivale a uma divisão pela base. No sistema binário, se fizermos n deslocamentos para a direita, o valor será dividido por 2n.

Existe um problema relacionado à divisão efetuada por um shift para a direita: um shift para a direita equivale a uma divisão de um número sem sinal por 2. Por exemplo, se deslocarmos uma posição para a direita a representação sem sinal de 254 (0FEh), obtemos 127 (07Fh), exatamente o esperado. Entretanto, se deslocarmos uma posição para a direita a representação binária de -2 (0FEh), obtemos 127 (07Fh), o que não está correto. Este problema ocorre porque estamos introduzindo um zero no bit sete. Se o bit sete contém 1 antes do deslocamento, indicativo de número negativo nos inteiros com sinal, e depois recebe zero, estamos alterando o sinal deste número (que passa de negativo para positivo). Como este não é o propósito da divisão... dá erro.
Para usar um shift para a direita como um operador de divisão, antes é preciso definir uma terceira operação de deslocamento: o deslocamento aritmético para a direita (arithmetic shift right). Um shift aritmético para a direita funciona como o shift para a direita normal, com uma diferença: ao invés de deslocar o bit sete para a posição seis, este bit é deixado intacto, ou seja, o bit sete não é zerado.

Isto geralmente produz o resultado esperado. Por exemplo, fazendo um shift aritmético para a direita com -2 (0FEh), obtemos -1 (0FFh). Uma coisa, no entanto, não pode ser esquecida: esta operação sempre arredonda os números para o inteiro que seja menor ou igual ao resultado, ou seja, arredonda para baixo. Um shift artimético para a direita com 5 dá como resultado 2. Mas preste atenção. Um shift aritmético para a direita com -1 dá como resultado -1, e não zero! O arredondamento se faz na direção do menor valor e -1 é menor do que 0. Este não é um "bug" no shift aritmético para a direita, é apenas como a divisão de inteiros foi definida.
Outra operação muito útil é a rotação para a esquerda e para a direita. Estas operações se comportam como os deslocamentos, com uma diferença importante: o bit que sai numa extremidade entra na extremidade oposta.


Campos Bit e Dados Compactados
Apesar do 80x86 operar eficientemente com tipos de dado byte, word e double word,
ocasionalmente teremos que trabalhar com tipos de dado que usam um número de bits
diferente do habitual (8, 16, 32 ou 64). Por exemplo, imagine uma data na forma "2/4/98". São três valores numéricos que representam uma data: valores para o dia, para o mês e para o ano. Os dias variam de 1 a 31, o que consome 5 bits (valor máximo de 32) para representar a entrada dos dias. Os meses variam de 1 a 12. Portanto, 4 bits são suficientes (valor máximo de 16). O valor para o ano, imaginando que trabalhemos com valores variando de 0 a 99, precisam de 7 bits (que podem representar até o valor 128). Somando os bits necessários, chega-se a 16 bits, o mesmo que 2 bytes. Em outras palavras, podemos acomodar nossos dados de data em dois bytes ao invés de três se usássemos um byte para cada um dos campos dia, mês e ano. Isto economiza um byte de memória para cada data armazenada, que pode representar uma economia substancial se tivermos que armazenar zilhões de datas. O arranjo dos bits pode ser visto na figura acima. DDDDD representam os 5 bits reservados para o valor do dia, MMMM representam os quatro bits para armazenar o mês e YYYYYYY são os sete bits reservados para o valor do ano. Cada coleção de bits representando um item de data é denominado campo bit. 2 de Abril de 1998 seria representado, respectivamente, pelos bits 00010 0100 1100010, ou seja, 1262h.

Os MMMM representam os quatro bits do valor mês, DDDDD representam os cinco bits do valor dia, e YYYYYYY são os setes bits do ano.Cada coleção d bits representa uma data no campo bit.2 de Abril de 1988 seria representado como 4158h:

Apesar dos valores compactados serem muito eficientes para economizar espaço (isto é,
eficientes em termos de uso de memória), computacionalmente são muito ineficientes. A razão é que dependem de instruções extras para descompactar os dados dos diversos campos bit. Estas operações adicionais consomem tempo e bytes adicionais para armazenar as instruções. Portanto, o planejamento prévio e o custo/benefício precisam ser bem analisados. Existem inúmeros exemplos de tipos de dados compactados. Pode-se compactar oito valores booleanos num único byte, pode-se acomodar dois dígitos BCD num byte, etc.
conjunto de caracteres ASCII
O conjunto dos caracteres ASCII (excluindo-se os caracteres expandidos definidos pela IBM) é dividido em quatro grupos de 32 caracteres. O primeiro grupo, códigos ASCII de 0 a 1Fh (31), formam um conjunto especial de caracteres não imprimíveis chamados de caracteres de controle. Recebem este nome porque realizam várias operações de controle de impressão/display ao invés de mostrarem símbolos. Exemplos incluem o retorno de carro (carriage return), que posiciona o cursor no lado esquerdo da linha atual, avanço de linha (line feed), que move o cursor uma linha para baixo no dispositivo de saída e o retorno (backspace), que move o cursor uma posição para a esquerda. Infelizmente os caracteres de controle realizam operações diferentes dependendo do dispositivo de saída. A padronização entre os dispositivos de saída é precária. Para saber exatamente como se comporta determinado caracter de controle em relação a um determinado dispositivo de saída é preciso consultar o manual do dispositivo.
O segundo grupo de 32 códigos de caracteres ASCII inclui vários símbolos de pontuação, caracteres especiais e algarismos. Os caracteres mais conhecidos deste grupo são o espaço (código ASCII 20h) e os algarismos (códigos ASCII de 30h a 39h). Lembre-se de que os algarismos diferem dos seus valores numéricos apenas no nibble mais significativo. Se subtrairmos 30h do código ASCII de qualquer um dos dígitos, obtemos o equivalente numérico deste dígito.
O terceiro grupo de caracteres ASCII é reservado para os caracteres alfabéticos maiúsculos. Os códigos ASCII para os caracteres de A a Z ficam no intervalo 41h a 5Ah (65 a 90). Como só existem 26 caracteres alfabéticos diferentes, os seis códigos restantes são de vários símbolos especiais.
Finalmente, o quarto grupo de 32 códigos de caracteres ASCII são reservdos para os símbolos alfabéticos minúsculos, cinco símbolos adicionais especiais e outro caracter de controle (delete). Observe que os símbolos dos caracteres minúsculos usam os códigos ASCII de 61h a 7Ah. Se convertermos os códigos dos caracteres maiúsculos e minúsculos para binário, é possível verificar que os símbolos maiúsculos diferem dos seus correspondentes minúsculos em apenas um bit (veja ao lado os códigos para os caracteres "E" e "e").

A única diferença entre estes dois códigos reside no bit 5. Caracteres maiúsculos sempre
possuem 0 no bit cinco, os minúsculos sempre possuem 1 no bit cinco. Podemos usar esta característica para converter rapidamente maiúsculas em minúsculas e vice versa. Se o caracter for maiúsculo, para forçá-lo para minúsculo basta setar o bit cinco para 1. Se o caracter for minúsculo, para forçá-lo para maiúsculo basta setar o bit cinco para 0.
Na realidade, os bits cinco e seis determinam o grupo ao qual o caracter ASCII pertence:
Bit 6 Bit 5 Grupo
0 0 Caracteres de controle
0 1 Dígitos e caracteres de pontuação
1 0 Maiúsculos e especiais
1 1 Minúsculos e especiais
Podemos, por exemplo, transformar qualquer caracter maiúsculo ou minúsculo (ou especial) no seu caracter de controle equivalente apenas zerando os bits cinco e seis.
Agora observe os códigos ASCII para os caracteres dos dígitos numéricos. A representação decimal destes códigos ASCII não esclarece grande coisa, mas a representação hexadecimal revela algo muito importante - o nibble menos significativo do código ASCII é o equivalente binário do número representado. Zerando o nibble mais significativo, converte-se o código do caracter para a sua representação binária. Inversamente, é possível converter um valor binário do intervalo de 0 a 9 para a sua representação ASCII simplesmente setando o nibble mais significativo em três. Note que é possível usar a operação lógica AND para forçar os bits mais significativos para zero e usar a operação lógica OR para forçar os bits mais significativos para 0011 (três).

Lembre-se de que não é possível transformar uma string de caracteres numéricos na sua
representação binária correspondente simplesmente zerando o nibble mais significativo de cada dígito da string. Transformando 123 (31h 32h 33h) desta maneira resulta em três bytes:
010203h, e não no valor correto que é 7Bh.
Transformar uma string de dígitos requer um pouco mais de sofisticação. A transformação explicada acima só serve para dígitos únicos. O bit sete no ASCII padrão é sempre zero. Isto significa que o conjunto de caracteres ASCII utiliza apenas a metade dos códigos possíveis num byte de oito bits. A IBM usa os 128 códigos restantes para vários caracteres especiais (caracteres com acento, etc), símbolos matemáticos e caracteres de desenho de linhas. Deve ficar claro que estes caracteres extras são uma extensão não padronizada do conjunto de caracteres ASCII. É claro que o nome IBM tem peso e a maioria dos computadores baseados no 80x86 e as impressoras acabaram incorporando os caracteres adicionais da IBM.
Apesar do fato de que sejam um padrão, codificar dados usando simplesmente caracteres padrão ASCII não garante a compatibilidade entre os sistemas, se bem que, hoje em dia, dificilmente encontraremos problemas. Como usaremos com frequência os caracteres ASCII em Assembly, seria interessante guardar de cabeça alguns códigos ASCII importantes, como o do "A", do "a" e do "0".
Meus leitores devem ser perguntar para que serve tudo isso?Na prática conforme fomos programando, tudo se tornará mais óbvio.Mas as funções booleanas servem para tomar decisões e principalmente circuitos.Quando quisermos escrever drivers ou controlar robôs, é muito importante conhecer, e se quisermos estudar as relações dos componentes eletrônicos.Aqui na internet existem muitos textos excelentes sobre eletrônica, e até melhores do que este.Mas quero ajudar um pouco.Em eletrônica existem circuitos combinacionais e sequenciais.Nesses circuitos poderemos ver que existem componentes que funcionam como os operadores booleanos AND,OR e NOT.Quando estiver escrevendo driver leia os manuais do fabricante do produto e você verá símbolos como esse(existentes em eletrônica):
Na ordem exata, temos da esquerda para direita símbolo de AND, OR e NOT(também conhecido como inversor).São chamadas de portas em eletrônica.Ainda há combinações dessas portas, como a função NAND:
Um exemplo de circuito combinacional mais óbvio que tem , é um LED ou decodificador de sete segmentos.Aquela luzinha que tem no rádio relógio.
Isto é um circuito combinacional que possui quatro entradas e determina os sete segmentos de LED estejam em lógica 1(ligada) ou lógica 0(desligada).Como ele contém sete segmentos ou saídas, serão sete funcçoes lógicas associadas a isso.A figura abaixo fornece os devidos segmentos para determinados números decimais:
As quatro entradas, cada uma sendo uma função booleana,equivalem a 4 bits de um número binário no intervalo entre 0 e 9.Se D é o maior valor ou bit mais significativo, e A o menor número ou bit mais menos significativo para este número.Cada função lógica deveria produzir um segmento ligado para uma dada entrada, se um segmento particular fosse iluminado.Por exemplo,S4(segmento 4) deveria estar ligado para o valor binário 0000,0010,0110 e 1000.Para cada valor que ilumina um segmento, você deveria ter um minitermo na equação lógica:
S4 = D'C'B'A' + D'C'BA' + D'CBA' + DC'B'A'.
Vamos esclarecer mais isso daí:
Seguindo a sequencia de número de 0 a 9 em decimal, temos que os valores binários são,respectivamente:DCBA = 0000 - 1001.
E = D’C’B’A’ + D’C’BA’ + D’C’BA + D’CB’A + D’CBA’ + D’CBA + DC’B’A’ + DC’B’A
F = D’C’B’A’+ D’CB’A’ + D’CB’A + D’CBA’ + DC’B’A’ + DC’B’A
G = D’C’B’A’ + D’C’B’A + D’C’BA’ + D’C’BA + D’CB’A’ + D’CBA + DC’B’A’ + DC’B’A
H = D’C’BA’ + D’C’BA + D’CB’A’ + D’CB’A + D’CBA’ + DC’B’A’ + DC’B’A
I = D’C’B’A’ + D’C’BA’ + D’CBA’ + DC’B’A’
J = D’C’B’A’ + D’C’B’A + D’C’BA + D’CB’A’ + D’CB’A +D’CBA’ + D’CBA + DC’B’A’ + DC’B’A
K = D’C’B’A’ + D’C’BA’ + D’C’BA + D’CB’A + D’CBA’ + DC’B’A’
Portanto, acima vemos que para cada segmento temos uma função lógica que o aciona. E por aí vai. Você pode construir circuitos por adição, multiplicação, subtração, comparação usando lógica combinacional.
Referências Bibliográficas:
Por favor, consultar um tópico no blog assim denominado. Tenho muitas referências e estou sempre atualizando...!

Nenhum comentário:
Postar um comentário