Docsity
Docsity

Prepare-se para as provas
Prepare-se para as provas

Estude fácil! Tem muito documento disponível na Docsity


Ganhe pontos para baixar
Ganhe pontos para baixar

Ganhe pontos ajudando outros esrudantes ou compre um plano Premium


Guias e Dicas
Guias e Dicas


Modo grafico do Nasm, Manuais, Projetos, Pesquisas de Programação Assembly

Este documento fala sobre o modo grafico no montador Nasm, os diversos conceitos abordados sobre: Cores, modos utilizados, resoluçoes, etc..

Tipologia: Manuais, Projetos, Pesquisas

2021

Compartilhado em 10/07/2021

bft-corporations
bft-corporations 🇧🇷

2

(1)

2 documentos

1 / 23

Toggle sidebar

Esta página não é visível na pré-visualização

Não perca as partes importantes!

bg1
Pedro Araújo, UBI-DI 1/23
Introdução ao Assembler FASM Flat Assembler (versão preliminar)
1 Introdução
Este texto constitui uma pequena introdução ao assembler FASM(Flat Assembler). Embora
contenha algumas notas relacionadas com a arquitectura de computadores e programação em
baixo-nível, não é um manual de programação. Pretende ser apenas um auxiliar para apoiar os
primeiros passos na programação em assembly usando o assembler FASM.
O primeiro conceito que importa esclarecer é precisamente a distinção entre aqueles dois termos
realçados a itálico. Assim, o termo assembly refere-se à linguagem de programação, que é também
designada por linguagem de baixo-nível, uma vez que se encontra intimamente relacionada com o
processador a que se destina. Deste modo, cada processador, de cada fabricante(Intel, AMD,
Motorola,...), tem o seu próprio assembly, já que cada um tem estrutura interna diferente, mas o termo
assembly aplica-se a todos eles (i.e. não há uma linguagem “assembly Intel” ou “assembly AMD”, tal
como existe Pascal ou C). O que acontece é dizer-se que se está a utilizar o assembly do Pentium, do
Athlon, ou do Motorola68000. Em princípio, um programa que utilize o assembly do Pentium não será
executado por um processador de outro fabricante, a menos que sejam compatíveis entre si.
Pelo seu lado, o termo assembler (“montador” em inglês) refere-se a um programa que permite
facilitar o trabalho com a linguagem assembly, fazendo com que esta se assemelhe um pouco mais a
uma linguagem de alto-nível. De facto, torna-se muito complicado para os programadores humanos
escrever programas usando a linguagem “pura” do processador (linguagem-máquina), a qual é
constituída por um conjunto mais ou menos extenso de bits (ex: a instrução “mov ah,40h”, muito
usada em assembly, corresponde a 1011010010000000, de facto bits é a única coisa que as máquinas
“entedem” !). O assembler atribui nomes (mnemónicas) aos conjuntos de bits que constituem as
instruções do processador, facilitando a sua compreensão pelos humanos. O assembler também chama
a si a execução de um conjunto de acções necessárias para que um programa possa ser executado
(p.ex. o controlo de certos registos do processador), escondendo essas operações ao programador.
A programação em assembly apresenta algumas características próprias. A primeira é que permite
escrever programas que executam muito mais rapidamente que programas escritos em linguagens de
alto-nível. Isto deve-se ao facto de que os compiladores ou interpretadores destas linguagens, ao
traduzirem as suas instruções para assembly, o fazerem de forma pouco eficiente, gerando mais
instruções assembly do que um programador humano pode conseguir se programar directamente em
baixo-nível. Para tirar partido deste facto, quase todas as linguagens de alto-nível permitem que se
possam embutir instruções assembly entre as instruções da própria linguagem, precisamente naqueles
sítios em que for detectado que a execução do programa está a gastar mais tempo. Os programas
escritos em assembly ficam assim mais pequenos e logo mais rápidos. Uma outra característica do
assembly é o controle que proporciona sobre os componentes de hardware, em particular do
processador, permitindo usar todas as suas funcionalidades e capacidades. Importa notar que certas
linguagens de alto-nível impedem ou limitam o acesso a certos componentes de hardware, com a
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17

Pré-visualização parcial do texto

Baixe Modo grafico do Nasm e outras Manuais, Projetos, Pesquisas em PDF para Programação Assembly, somente na Docsity!

Introdução ao Assembler FASM – Flat Assembler ( versão preliminar )

1 Introdução

Este texto constitui uma pequena introdução ao assembler FASM(Flat Assembler). Embora contenha algumas notas relacionadas com a arquitectura de computadores e programação em baixo-nível, não é um manual de programação. Pretende ser apenas um auxiliar para apoiar os primeiros passos na programação em assembly usando o assembler FASM. O primeiro conceito que importa esclarecer é precisamente a distinção entre aqueles dois termos realçados a itálico. Assim, o termo assembly refere-se à linguagem de programação, que é também designada por linguagem de baixo-nível, uma vez que se encontra intimamente relacionada com o processador a que se destina. Deste modo, cada processador, de cada fabricante(Intel, AMD, Motorola,...), tem o seu próprio assembly , já que cada um tem estrutura interna diferente, mas o termo assembly aplica-se a todos eles (i.e. não há uma linguagem “assembly Intel” ou “assembly AMD”, tal como existe Pascal ou C). O que acontece é dizer-se que se está a utilizar o assembly do Pentium, do Athlon, ou do Motorola68000. Em princípio, um programa que utilize o assembly do Pentium não será executado por um processador de outro fabricante, a menos que sejam compatíveis entre si. Pelo seu lado, o termo assembler (“montador” em inglês) refere-se a um programa que permite facilitar o trabalho com a linguagem assembly , fazendo com que esta se assemelhe um pouco mais a uma linguagem de alto-nível. De facto, torna-se muito complicado para os programadores humanos escrever programas usando a linguagem “pura” do processador (linguagem-máquina), a qual é constituída por um conjunto mais ou menos extenso de bits (ex: a instrução “mov ah,40h”, muito usada em assembly, corresponde a 1011010010000000, de facto bits é a única coisa que as máquinas “entedem” !). O assembler atribui nomes (mnemónicas) aos conjuntos de bits que constituem as instruções do processador, facilitando a sua compreensão pelos humanos. O assembler também chama a si a execução de um conjunto de acções necessárias para que um programa possa ser executado (p.ex. o controlo de certos registos do processador), escondendo essas operações ao programador.

A programação em assembly apresenta algumas características próprias. A primeira é que permite escrever programas que executam muito mais rapidamente que programas escritos em linguagens de alto-nível. Isto deve-se ao facto de que os compiladores ou interpretadores destas linguagens, ao traduzirem as suas instruções para assembly , o fazerem de forma pouco eficiente, gerando mais instruções assembly do que um programador humano pode conseguir se programar directamente em baixo-nível. Para tirar partido deste facto, quase todas as linguagens de alto-nível permitem que se possam embutir instruções assembly entre as instruções da própria linguagem, precisamente naqueles sítios em que for detectado que a execução do programa está a gastar mais tempo. Os programas escritos em assembly ficam assim mais pequenos e logo mais rápidos. Uma outra característica do assembly é o controle que proporciona sobre os componentes de hardware, em particular do processador, permitindo usar todas as suas funcionalidades e capacidades. Importa notar que certas linguagens de alto-nível impedem ou limitam o acesso a certos componentes de hardware, com a

finalidade de evitar que possam ser desencadeadas acções potencialmente perigosas. Porém, em algumas situações, pode ser necessário o acesso a essas funcionalidades do hardware, o que pode ser conseguido através do assembly. Entretanto, uma vez que neste caso não existe um compilador para controlar as acções do programador, ficam por sua conta e risco as consequências dessas acções. Existem vários assemblers, entre os quais os mais famosos são o MASM(Microsoft) e o TASM(Borland), que são propriedade dos respectivos fabricantes e logo são pagos. Entre os exemplos gratuitos temos o NASM( http://sourceforge.net/projects/nasm) e o FASM que pode ser descarregado de http://flatassembler.net/, onde para além do próprio programa pode ser encontrada literatura de apoio, exemplos, utilitários, etc. De um modo geral, o FASM é mais fácil de utilizar do que outros programas similares. Nas alíneas seguintes apresentam-se algumas das suas principais características.

Antes de passar à análise dos aspectos mais relevantes relacionados com a escrita de programas em assembly usando o FASM, convém rever alguns conceitos referentes ao tratamento da informação por parte dos computadores digitais.

2 Codificação da informação

Os computadores digitais usam bits para representar a mais pequena quantidade de informação. De facto, um bit (binary digit) assume apenas um de dois estados possíveis designados por false e true , habitualmente representados respectivamente por “F” e “T” ou “0” e “1” (neste texto será utilizada a segunda terminologia). Esta codificação diz-se binária precisamente porque existem apenas dois estados possíveis para um bit. Em termos de implementação física esses dois estados são traduzidos pela não existência de uma grandeza eléctrica como corrente ou tensão para o caso do “0” e pela existência de um certo valor para essa grandeza, habitualmente o valor de tensão de 5V, para o caso do “1”. Se com um bit podem ser representados dois estados (0,1), então com dois bits podem representar-se quatro estados (00,01,10,11), três bits permitem oito casos, etc; de cada vez que se

acrescenta um bit duplicam os casos. A regra é que com n bits podem codificar-se m  2 n casos.

2.1 Representação de valores numéricos

A expressão da significância posicional constante do AnexoC, indica o modo como os bits podem ser usados para representar valores numéricos usando apenas os algarismos binários 0 e 1, tal como as pessoas o fazem usando os algarismos decimais de 0 a 9. Os números são frequentemente representados noutras bases para além da binária, para simplificar o seu tratamento. Como a informação contida num bit é pequena (apenas 0 ou 1) torna-se necessário trabalhar com um grande número deles para representar informação realmente útil. Assim, recorre-se ao agrupamento dos bit em unidades maiores (byte, Kbyte,...) ou ainda à representação dos valores noutras bases de numeração, o que corresponde ao agrupamento dos bit em unidades maiores (p. ex. cada algarismo hexadecimal é formado por quatro algarismos binários). A partir daqui define-se uma aritmética binária, que permite realizar as operações aritméticas usando dados binários, tal como na aritmética decimal.

Situação diferente ocorre quando o valor introduzido pelo teclado corresponde a um valor numérico, como um inteiro. Tomando como exemplo o valor 741 (valor em base decimal), tal como no caso anterior cada tecla gera o código ASCII que lhe corresponde, ou seja 37h+34h+31h. Se este valor for armazenado num ficheiro de texto tudo se passa como anteriormente. Ao ler o ficheiro aqueles códigos são de novo convertidos para os caracteres ASCII e no ecrã aparecerá 741. O primeiro aspecto que importa entender é que o que aparece no ecrã é sempre texto, portanto 741 é por assim dizer a palavra “741” (tal como no caso anterior a palavra era “hello”), ou, dito de outro modo, trata-se do símbolo “7”, seguido do símbolo “4”, seguido do símbolo “1”. Cada um daqueles símbolos não tem qualquer relação com os outros, apenas estão dispostos em sequência; parece um número apenas porque estamos habituados a interpretar como números as sequências de símbolos formadas por algarismos.

Mas, e se este valor deve ser tratado como um número inteiro? Por exemplo se for necessário operar sobre ele, como multiplicá-lo por outro? É claro que não podem aplicar-se operações aritméticas sobre sequências de símbolos, é preciso fazer com que essas sequências sejam números. No exemplo em estudo é preciso fazer com que a sequência 741 deixe de ser um “7” encostado a um “4” por sua vez encostado a um “1” e passe a ser 710^2 +410^1 +110^0 =741. O que deverá então fazer um programa ao ler um valor para uma variável do tipo inteiro? Enquanto não se carrega na tecla “Enter” o buffer de teclado vai armazenando os códigos ASCII das teclas que vão sendo introduzidas (37h+34h+31h no exemplo). A partir do momento em que se carrega no Enter indica-se à máquina que a introdução do valor terminou e que a sequência de códigos deve ser convertida para um inteiro. A primeira operação é obter o valor numérico de cada algarismo a partir do respectivo código ASCII. Ora como o código ASCII dos algarismos é dado pela soma de 30h com o próprio algarismo, basta retirar este 30h a cada código lido, para obter o valor numérico. No exemplo em estudo isso corresponde a fazer: 37h-30h=7, 34h-30h=4, 31h-30h=1. Como a máquina “sabe” que foram introduzidas três teclas, torna-se fácil aplicar a fórmula 710^2 +410^1 +110^0 de modo a obter

  1. Note-se que este 741 é agora um valor numérico e não meramente três caracteres alfanuméricos seguidos. Sendo assim, e para que possa sofrer operações aritméticas as quais são necessariamente

h e l l o teclado

68h 65h 6Ch 6Ch 6Fh … ficheiro de texto

ecrã

hello

setas a cheio (escrita no ficheiro): conversão caracteres → ASCII setas a tracejado(leitura do ficheiro): conversão ASCII → caracteres

tabela ASCII

6 8h h 65h e 6Ch l 6 Ch l 6Fh o

efectuadas em binário, deve ser aplicada a conversão para base 2, de que resulta: 74110 =02E5h=0000001011100101b (acrescentaram-se zeros à esquerda para obter dois bytes completos). O valor 741 é assim constituído pelos dois byte 02h e E5h, em que o primeiro tem mais peso (ou é mais significativo) que o segundo, sendo por isso designados por byte mais significativo ( high byte ) e byte menos significativo ( low byte ). Finalmente, que acontece se este valor tiver de ser guardado num ficheiro de inteiros? Como a memória é um conjunto de bytes organizados sequencialmente, de que modo são guardados os dois byte do valor? A figura seguinte ilustra os dois modos possíveis, designados por little endian e big endian 2. Os processadores da INTEL usam o modo little endian.

O diagrama a seguir esquematiza o que acontece quando a sequência de teclas “741” é tratada como uma cadeia de caracteres (texto) ou como um valor numérico (inteiro).

(^2) O termo endian tem origem no livro “As viagens de Gulliver” e refere-se à questão de qual dos lados os ovos devem ser quebrados.

E 02

.. .

.

.

..

.

n n+

n-

n+

02 E

.. .

.

.

..

.

n n+

n-

n+

little endian (usado pela INTEL) Neste modo o byte low é guardado no endereço inicial, seguido dos restantes bytes, parecendo o valor ficar invertido

big endian Neste modo o byte high é guardado no endereço inicial, seguido dos restantes bytes

Memória organizada sequencialmente em bytes

7 4 1 teclado

tabela ASCII

31h 1 34h 4 37h 7

ecrã 741

E5h 02h (little endian)

ficheiro de texto 37h 34h 31h

Conversão p/binário ficheiro de inteiros Conversão p/ASCII

37h 34h 31h

setas a cheio: tratamento de texto (cadeias de caracteres) setas a tracejado: tratamento de inteiros (valores numéricos)

74110 =02E5h (^) 02E5h=741 10

instrução, escrever por engano “lodab” em vez da instrução correcta “lodsb”, o FASM considera “lodab” uma label e não dá qualquer erro)

<instrução>  uma das instruções (mnemónicas) do FASM (ex: mov, add, jmp)

 constantes, variáveis, registos, etc, a que a instrução faz referência

Exemplo: mov al , 5 ;coloca o valor inteiro 5 no registo al cont: dec al ;define a label “cont” e decrementa de uma unidade o valor do registo al jnz cont ;salta (jump) para a linha anterior (aonde foi definida a label “cont”) se não ;resultou zero da última operação aritmética realizada (que foi “dec al”)

P. Qual a acção realizada por este pequeno programa? R. Decrementa o registo al desde o valor inicial 5, até atingir 0

5 .4 Pseudo-instruções: não correspondem a instruções verdadeiras do processador, mas permitem simplificar certas tarefas como definir constantes ou variáveis. Algumas delas são^3 :  declaração de dados inicializados: declara dados com valor inicial o DB-define byte  os valores são considerados bytes (8 bits) db 0x55 (define o byte 0x55) , db ‘a’ (carácter ‘a’) , db 0 (inteiro 0) , db 255 (inteiro 255 – maior valor representado por um byte), db ‘hello’,13,10 = db ‘h’,’e’,’l’,’l’,’o’,13,10 (define a string ‘hello’ seguida de CR/LF) o DW-define word  os valores são considerados words (16 bits) dw 0x1234 (define uma word constituída pelos bytes 0x34 0x12) dw ‘a’ (word 0x41 0x00) , dw ‘ab’ ( word 0x41 0x42) dw 65535 (inteiro 65535 – maior valor representado por uma word) o DD-define double word  os valores são considerados double-word (32 bits) dd 0x12345678 (define uma double-word constituída pelos bytes 0x78 0x56 0x34 0x12) dd 1.234567e20 (definição de uma constante em vírgula flutuante)

(^3) O FASM dispõe de várias outras; apresentam-se aqui apenas as que vão ser usadas nas aulas práticas

 declaração de dados não inicializados: reserva espaço para armazenar valores o RESB-reserve byte  buffer: resb 64 (reserva espaço para 64 bytes) o RESW-reserve word  wordvar: resw 1 (reserva espaço para uma word) o RESD-reserve double word  doublewordvar: resd 10 (array de 10 double-word) o comando EQU: atribui um valor a um símbolo (define uma constante) Ex: ecran EQU 1 ;define a constante “ecran” como sendo equivalente a 1

5.5 Referência a conteúdo/endereço de variáveis/memória

NOTA: o nome de uma variável representa o endereço de memória que foi atribuído a essa variável, mais propriamente o endereço do byte inicial dessa variável.

Ex: variáveis var1 tipo byte , var2 do tipo word (2 byte) e msg do tipo cadeia de caracteres:

var1 = E5h

var2 = 0001h

msg = ‘UBI’

referências ao conteúdo de uma variável ou posição de memória, exigem que o endereço correspondente seja colocado entre parêntesis rectos “[ ]” ; ex: mov ax, [ind1] ;move o conteúdo da variável ind1 para o registo ax (ax02E5h)

referências ao endereço das variáveis (i.e., à sua posição na memória ) não levam parêntesis ex: mov dx, ind2 ;move o endereço da variável ind2 para o registo dx (dxn+3)

 NOTA: não são permitidas referências à memória/variáveis para origem e destino de dados dentro da mesma instrução. Ex: mov [ind2] , [ind1]  ERRO: não é possível mover o conteúdo de uma variável(memória) directamente para outra variável(memória); o que deverá fazer-se é: mov ax , [ind1] ; usa-se um registo auxiliar (neste caso o ax), para mov [ind2] , ax ;permitir a operação

 endereços efectivos: qualquer operando de uma instrução que faz referência à memória. Exs: mov al, [msg] ;coloca no registo al o 1º byte do conteúdo da variável msg (al  55h=‘U’) mov ah, [msg+1] ;coloca no registo ah o 2º byte do conteúdo da variável msg (ah  42h=‘B’) mov bl, [msg+2] ;coloca no registo ah o 3º byte do conteúdo da variável msg (bl  49h=‘I’)

.. .

.

n- 1 n n+ n+ n+ n+ n+ n+ n+.. .

.

conteúdo da variável var 1

conteúdo da variável var 2 conteúdo da variável msg

endereços de memória 1byte

55h(U) 42h(B) 49h(I)

E5h 01 h 00h

endereço da variável var endereço da variável var endereço da variável msg

Exs: Decimal  143 = 143 10 = 110^2 +110^1 +110^0  notação por defeito Hexadecimal  013Ch = 116^2 +116^1 +1216^0 = 284  valores hexadecimais terminam em "h" (os valores devem começar sempre por dígitos)  0x13C – outro modo de representar valores em hexadecimal Octal  765q=78^2 +68^1 +58^0 =501  valores octais terminam em "q" Binário  1001b = 12^3 +02^2 +02^1 +1*2^0 = 9  valores binários terminam em "b"

2)Character: uma constante deste tipo consiste num máximo de quatro caracteres entre plicas ou aspas (se forem usadas as plicas dentro da constante poderão aparecer as aspas e vice-versa) Ex: ‘ab’ , “abcd” , ‘”xy”’, “’yx’”

3)String: só são possíveis de usar com as pseudo-instruções DB, DW, DD. Uma constante do tipo string é semelhante a uma do tipo character, apenas é maior. Ex: msg db ‘Ola mundo’  db ‘Ola’ , ’ ‘ , ’mundo’ - string msg1 db ’Bola’  db ’B’,’o’,’l’,’a’ - é uma string devido a pertencer à pseudo-instrução “db”, apesar de que tendo só quatro caracteres poderia ser considerada character

4)Floating-point(reais): só possíveis com a pseudo-instrução DD. Apresentam-se no formato: . [ ] [E ] – o ponto decimal é obrigatório para que o FASM possa distinguir entre inteiros e reais; [ ] significa que é opcional. Exs: dd 1.2 ;1. dd 1.3e2  dd 1.3e+2 ;130. dd 14.e-1 ;1. dd 3.14 ;pi

7 Exemplo de programa: escrever no ecrã a string "Ola mundo"

org 100h

mov ah, 40h ;ah ← 40h (função de escrita) mov bx, 1 ;bx ← 1 (1=ecrã) mov cx, 9 ;cx ← 9 (número de caracteres a escrever ) mov dx, msg ;dx ← endereço da variável "msg" (dx aponta para os dados a escrever) int 21h ;provoca a execução da acção (escrita) mov ah, 4Ch ;ah ← 4Ch (função para terminar a execução de um programa) int 21h ;provoca a execução da acção (termina o programa)

section .data msg db “Ola mundo” ;define a variável "msg"

Observe a estrutura e a legibilidade do programa acima; compare com o seguinte:

ORG 100h MOV ah, 40h ;ah ← 40h (FUNÇÃO DE ESCRITA) Mov BX, 1 ;bx ← 1 (1=ecrã) MOV cx, 9 ;cx ← 11 (número de caracteres a escrever ) mOV DX, MSG ;dx ← endereço da variável "msg" (dx aponta para os dados a escrever) INT 21h ;PROVOCA a execução da acção (escrita) moV AH, 4Ch ;ah ← 4Ch (função para terminar a execução de um programa) INT 21H ;provoca a EXECUÇÃO da acção (termina o programa) SECTion .DATA msg DB “Ola mundo” ;DEFINE A VARIÁVEL "msg"

AnexoA – Tabela ASCII Tabela ASCII (7bits) Dec Hex Char Dec Hex Char Dec Hex Char Dec Hex Char 0 00h ^@ Null 32 20h 64 40h @ 96 60h ` 1 01h  ^A SOH-Start of Header^33 21h!^65 41h A^97 61h a 2 02h ☻ ^B STX- Start of Text 34 22h "^66 42h B^98 62h b 3 03h ♥ ^C ETX- End of Text 35 23h #^67 43h C^99 63h c 4 04h (^)  ^D EOT- End of Transmission 36 24h $^68 44h D^100 64h d 5 05h ♣ ^E ENQ- Enquiry 37 25h %^69 45h E^101 65h e 6 06h ♠ ^F ACK-^ Acknowledgment^38 26h &^70 46h F^102 66h f 7 07h ● ^G^ BEL- Bell 39 27h '^71 47h G^103 67h g 8 08h ◘ ^H^ BS- Backspace 40 28h (^72 48h H^104 68h h 9 09h (^) ○ ^I HT-Horizontal Tab 41 29h ) 73 49h I 105 69h i 10 0Ah (^) ◙ ^J LF-Line Feed 42 2Ah * 74 4Ah J 106 6Ah j 11 0Bh (^) ♂ ^K VT-Vertical Tab 43 2Bh + 75 4Bh K 107 6Bh k 12 0Ch ♀ ^L^ FF-Form Feed^44 2Ch ,^76 4Ch L^108 6Ch l 13 0Dh ♪ ^M^ CR-Carriage Return^45 2Dh -^77 4Dh M^109 6Dh m 14 0Eh ♫ ^N^ SO-Shift Out 46 2Eh.^78 4Eh N^110 6Eh n 15 0Fh ☼ ^O SI- Shift In 47 2Fh / 79 4Fh O 111 6Fh o 16 10h (^) ► ^P DLE- Data Link Escape 48 30h 0 80 50h P 112 70h p 17 11h (^) ◄ ^Q DC1- (XON) Device Control1 49 31h 1 81 51h Q 113 71h q 18 12h ↨ ^R^ DC2-^ Device Control2^50 32h 2 82 52h R^114 72h r 19 13h ‼ ^S^ DC3-^ (XOFF) Device Control3^51 33h 3 83 53h S^115 73h s 20 14h ¶ ^T^ DC4- Device Control4 52 34h 4 84 54h T^116 74h t 21 15h § ^U^ NAK- Negative Acknowledge 53 35h 5 85 55h U^117 75h u 22 16h ▄ ^V^ SYN- Synchronous Idle 54 36h 6 86 56h V^118 76h v 23 17h (^) ↨ ^W ETB- End of Trans. Block 55 37h 7 87 57h W 119 77h w 24 18h (^) ↑ ^X CAN- Cancel 56 38h 8 88 58h X 120 78h x 25 19h ↓ ^Y^ EM-^ End of Medium^57 39h 9 89 59h Y^121 79h y 26 1Ah → ^Z^ SUB-^ Substitute^58 3Ah :^90 5Ah Z^122 7Ah z 27 1Bh ← ^[^ ESC-^ Escape^59 3Bh ;^91 5Bh [^123 7Bh { 28 1Ch └ ^^ FS- File Separator 60 3Ch <^92 5Ch ^124 7Ch | 29 1Dh (^) ↔ ^] GS- Group Separator 61 3Dh = 93 5Dh ] 125 7Dh } 30 1Eh (^) ▲ ^ ^ RS- Record Separator 62 3Eh > 94 5Eh ^ 126 7Eh ~ 31 1Fh ▼ ^_^ US-^ Unit Separator^63 3Fh?^95 5Fh _^127 7Fh ⌂  o sinal “ ^ “ antes de uma letra, significa carregar na tecla Control e simultaneamente nessa tecla  caracteres de 0(00h) a 31(1Fh) – são caracteres especiais, que executam funções de controlo;  carácter 32(20h) – corresponde ao código da tecla de espaço; a partir daqui e até ao carácter 126(7Eh) os caracteres têm expressão visível e podem ser impressos;  carácter 127(7Fh) – corresponde ao código da tecla DEL (delete);  os códigos das letras maiúsculas são inferiores aos das minúsculas diferindo por um valor igual ao código da tecla de espaço 32(20h). Ex. ASCII(‘a’) = ASCII(‘A’) + ASCII(‘ ‘)  97=65+32 (61h=41h+20h);  o código ASCII dos algarismos de 0 a 9, é dado pela soma do código do algarismo “0” que é 48(30h), mais o próprio algarismo decimal (em ASCII isso corresponde a preceder o algarismo decimal do algarismo “3”). Ex. ASCII(‘5’) = 48+5(30h+5)=53(35h);  o carácter 0(00h) designado por “null” é muitas vezes usado como terminador de strings (null terminated strings) e também para marcar o fim de ficheiros binários;  ^Z – é frequentemente utilizado para marcar fim de ficheiro de texto

Tabela ASCII estendida Dec Hex C Dec Hex C Dec Hex C Dec Hex C Dec Hex C 128 80h Ç 154 9Ah Ü 180 B4h ┤ 206 CEh ╬ 232 E8h Φ 129 81h ü 155 9Bh ¢ 181 B5h ╡ 207 CFh ╧ 233 E9h 130 82h é 156 9Ch £ 182 B6h ╢ 208 D0h ╨ 234 EAh Ω 131 83h â 157 9Dh ¥ 183 B7h ╖ 209 D1h ╤ 235 EBh δ 132 84h ä 158 9Eh ₧ 184 B8h ╕ 210 D2h ╥ 236 ECh ∞ 133 85h à 159 9Fh ƒ 185 B9h ╣ 211 D3h ╙ 237 EDh φ 134 86h å 160 A0h á 186 BAh ║ 212 D4h ╘ 238 EEh ε 135 87h ç 161 A1h í 187 BBh ╗ 213 D5h ╒ 239 EFh ∩ 136 88h ê 162 A2h ó 188 BCh ╝ 214 D6h ╓ 240 F0h ≡ 137 89h ë 163 A3h ú 189 BDh ╜ 215 D7h ╫ 241 F1h ± 138 8Ah è 164 A4h ñ 190 BEh ╛ 216 D8h ╪ 242 F2h ≥ 139 8Bh î 165 A5h Ñ 191 BFh ┐ 217 D9h ┘ 243 F3h ≤ 140 8Ch ì 166 A6h ª 192 C0h └ 218 DAh ┌ 244 F4h ⌠ 141 8Dh Ä 167 A7h º 193 C1h ┴ 219 DBh █ 245 F5h ⌡ 142 8Eh (^) Å 168 A8h (^) ¿ 194 C2h (^) ┬ 220 DCh (^) ▄ 246 F6h (^) ÷ 143 8Fh É 169 A9h ⌐ 195 C3h ├ 221 DDh ▌ 247 F7h ≈ 144 90h (^) æ 170 AAh (^) ¬ 196 C4h (^) ─ 222 DEh (^) ▐ 248 F8h (^) ° 145 91h (^) Æ 171 ABh (^) ½ 197 C5h (^) ┼ 223 DFh (^) ▀ 249 F9h (^) ∙ 146 92h (^) ô 172 ACh (^) ¼ 198 C6h (^) ╞ 224 E0h (^) α 250 FAh (^) · 147 93h (^) ö 173 ADh (^) ¡ 199 C7h (^) ╟ 225 E1h (^) ß 251 FBh (^) √ 148 94h ò 174 AEh « 200 C8h ╚ 226 E2h Γ 252 FCh ⁿ 149 95h (^) ò 175 AFh (^) » 201 C9h (^) ╔ 227 E3h (^) π 253 FDh (^) ² 150 96h (^) û 176 B0h (^) ░ 202 CAh (^) ╩ 228 E4h (^) Σ 254 FEh (^) ■ 151 97h ù 177 B1h ▒ 203 CBh ╦ 229 E5h σ 255 FFh 152 98h (^) ÿ 178 B2h (^) ▓ 204 CCh (^) ╠ 230 E6h (^) μ 153 99h Ö 179 B3h │ 205 CDh ═ 231 E7h τ Nota: os caracteres da tabela estendida dependem das definições de páginas de caracteres, feitas no ficheiro config.sys (ansi.sys e country.sys )

Códigos de algumas teclas (scan codes) Devolvidos pelo int 16h(função 10h) e int 21h(funções 06h e 07h) Tecla Código Tecla Código Tecla Código F1 3Bh Seta p/cima 48h F2 3CH Seta p/baixo 50h F3 3Dh Seta p/esquerda 4Bh F4 3Eh Seta p/direita 4Dh F5 3Fh Home 47h F6 40h End 4Fh F7 41h PgUp 49h F8 42h PgDn 51h F9 43h Insert 52h F10 44h Delete 53h F11 7Bh F12 7Ah

AnexoC - Métrica binária

Pessoas Computadores Facilidade no reconhecimento de símbolos, estados ou níveis Apenas dois estados básicos: ligado(0) e desligado(1) Base decimal (B=10) Base binária (B=2) 10 símbolos(alagarismos): 0, .. ,9 2 símbolos(algarismos): 0 , 1 [ bit ]

De acordo com a expressão de significância posicional que rege os sistemas de numeração, tem-se que para um código binário constituído por n bits, o seu valor em decimal (base 10) é:

n i

M Ai Bi An Bn An Bn A B A B

0

10 * * 1 *^1 ... 1 *^10 *^0

em que B é a base de numeração ( B =2 em binário), Ai são os algarismos da base (0 ou 1 em binário), Bi^ o peso ou significância posicional do algarismo Ai , sendo i o índice posicional do algarismo. Para o caso de n =1, 2, 3 e 4, obtém-se:

decimal

binário (pesos) 23 22 21 20 8 4 2 1

hexadecimal n

0 0 0 0 (^0 0) n= (2 casos) n= (4 casos) n= 3 (8 casos)

n= (16 casos)

1 0 0 0 1 1 2 0 0 1 0 2 3 0 0 1 1 3 4 0 1 0 0 4 5 0 1 0 1 5 6 0 1 1 0 6 7 0 1 1 1 7 8 1 0 0 0 8 9 1 0 0 1 9 10 1 0 1 0 A 11 1 0 1 1 B 12 1 1 0 0 C 13 1 1 0 1 D 14 1 1 1 0 E 15 1 1 1 1 F Note-se que para um certo número n de bits o maior valor decimal representado é 2 n -

Alguns exemplos com interesse em tecnologia dos computadores são:

n gama=2n^ designação 1 2 : (0 , 1) bit 4 16 : (0 .. 15) nibble 8 256 : (0 .. 255) byte 10 1024 : (0 .. 1023) Kbit 16 65536 : (0 .. 65535) Palavra 16 bits (word) 32 232 : (0 .. 2^32 -1) Palavra 32 bits 64 264 : (0 .. 2^64 -1) Palavra 64 bits

Dentre os exemplos anteriores, o byte (binary term), também designado por octeto, assume grande importância, uma vez que historicamente tem sido utilizado como o grupo mínimo de bits usado para representar a informação. Efectivamente, o tratamento de dados na forma digital não é habitualmente feito usando-se os bits 0 e 1 individualmente (embora haja casos em que isso acontece), mas sim em grupos, de que o byte (8 bits) é o mais universalmente usado. Por sua vez os grupos nibble (metade de um byte ) e word (dois byte ) são também muito utilizados.

O caso n =10 (Kbit) assume especial importância. O prefixo K significa 1000=10^3 em decimal, em que 10 é a base da numeração decimal e 3 é o expoente a que esta deve ser elevada para obter 1000. De acordo com este princípio, para em binário obtermos o valor de K, deveríamos elevar a base 2 a um expoente tal que se obtivesse 1000, ou seja 1000=2n, só que não existe nenhum expoente inteiro que verifique aquela relação; o valor mais próximo é 10, obtendo-se 2^10 =1024, pelo que em binário K=1024.

A partir da unidade byte definem-se os seus múltiplos, entre os quais: binário gama unidade (^) aproximadodecimal 210 1024 byte K (Kilo) - Kbyte 103 220 10241Kbyte=1 048 576 byte M (Mega) - Mbyte 106 230 10241Mbyte=1 073 741 824 byte G (Giga) - Gbyte 109 240 1024*1Gbyte=1 099 511 627 776 byte T (Tera) - Tbyte 1012

Tabela das potências de 2

n 2 n(decimal) 2 n(hexadecimal) unidade 0 1 1 1 2 2 2 4 4 3 8 8 4 16 10h 5 32 20h 6 64 40h 7 128 80h 8 256 100h 9 512 200h 10 1024 400h 1K 11 2048 800h 2K 12 4096 1000h 4K 13 8192 2000h 8K 14 16384 4000h 16K 15 32768 8000h 32K 16 65536 10000h 64K Para cada valor de n a gama de representação é dada pelo intervalo [0 .. 2 n -1]

AnexoE – Interrupções do DOS e da BIOS

DOS – Disk Operating System

int 21h – Diversas funções do DOS Função Descrição Registos

06H

Obtém um carácter do teclado e mostra-o no ecrã. Não espera que se carregue numa tecla. No caso de teclas especiais, (F1,F2,...), o registrador AL conterá o valor 0, sendo necessário chamar a função novamente para obter o código da tecla. O carácter 255 não pode ser usado pois significa “receber”

Entrada

AH=06H

DL=0-254 Envia o código da tecla DL=FFH(255) Recebe um carácter

Saída

Se DL=0-254, não tem retorno algum Se DL=255: ZF=1  não houve leitura ZF=0  AL=carácter lido

07H

Obtém um carácter do teclado sem o mostrar no ecrã. Espera que se carregue numa tecla. No caso de teclas especiais, (F1,F2,...), o registrador AL conterá o valor 0, sendo necessário chamar a função novamente para obter o código da tecla.

Entrada AH=07H

Saída AL=carácter lido

3CH Cria um ficheiro (handle)

Entrada

AH=3CH

CX=atributo (0= ficheiro normal) DS=segmento (desnecessário em FASM) DX= path para o ficheiro (ASCIIZ)

Saída

CF=0  OK  AX=handle do ficheiro CF=1  Erro  AX= 3 – path não encontrado 4 – sem handles disponíveis 5 – acesso não permitido

3DH Abre um ficheiro (handle)

Entrada

AH=3DH

AL=método de acesso: 00H – só leitura 01H – só escrita 02H – leitura/escrita DS=segmento (desnecessário em FASM) DX= path para o ficheiro (ASCIIZ)

Saída

CF=0  OK  AX=handle do ficheiro CF=1  Erro  AX= 1 – função inválida 2 – ficheiro não encontrado 3 – path não encontrado 4 – sem handles disponíveis 5 – acesso não permitido 12 – código de acesso inválido

3EH

Fecha ficheiro (handle) NOTA: não indicar valores de handle 0..4 pois referem-se a ficheiros de sistema que uma vez fechados não podem ser acedidos.

Entrada AH=3EH BX=handle do ficheiro

Saída CF=0 CF=1^ ^ OKErro^ ^ AX=handle do ficheiroAX= código de erro

3FH

Lê de um dispositivo ou ficheiro(handle) (handle = ponteiro para o dispositivo ou ficheiro)

Entrada

AH=3FH

BX=handle do ficheiro (0=teclado) CX=número de bytes a ler DX=endereço da variável de leitura Saída CF=0 CF=1^ ^ AX=número de bytes lidosErro  AX= código de erro

40H

Escreve em um dispositivo ou ficheiro(handle) (handle = ponteiro para o dispositivo ou ficheiro)

Entrada

AH=40H

BX=handle do ficheiro (1=ecrã) CX=número de bytes a escrever DX=endereço da variável de escrita Saída Se CF=0, AX=número de CF=1, Erro  AX= código de erro^ bytes escritos

4CH Termina a execução de um programa

Entrada AH=4CH Saída

AL= código de retorno (para chamadas dentro de ficheiros batch, pode ser testado por ERRORLEVEL)

BIOS – Basic Input/Output System int 12h - Memória Função Descrição Registos Obtém a quantidade total de memória do sistema. PC , XT  Mem = 640 Kbyte AT  não inclui memória de vídeo nem memória estendida

Entrada

Saída AX= quantidade de memória em blocos contínuos de 1 Kbyte

int 15h – Serviços do sistema Função Descrição Registos

88H

Obtém a quantidade de memória estendida do sistema (acima de 1Mb=1024Kb)

Entrada AH=88H Saída AX= quantidade de memória em blocos contínuos de 1 Kbyte acima de 1 Mb int 16h - Teclado Função Descrição Registos

00H

Obtém um carácter do teclado, sem o mostrar no ecrã. Devolve o “scan code” da tecla e o seu código ASCII se tiver algum. Funciona também para as teclas especiais (F1,F2,...).

Entrada AH=00H

Saída

AH=scan code (código da tecla no teclado) AL=código ASCII da tecla ou E0H(?) se a tecla é especial (F1,F2,...)

01H

Verifica se no buffer do teclado existe algum carácter para ser lido. Não remove o carácter; para o fazer usar a função 10H. Funciona também para as teclas especiais (F1,F2,...).

Entrada AH=01H

Saída

CF=0  existe carácter AH=scan code (código da tecla no teclado) AL=código ASCII da tecla ou E0H(?) se a tecla é especial (F1,F2,...)