Você está na página 1de 10

MÁQUINAS MULTINÍVEIS - CONTINUAÇÃO

Máquinas multiníveis: nível de máquina de sistema operacional, nível de


linguagem de montador e nível de linguagem orientada a problema.

O nível 3 é denominado nível do sistema operacional.


Um sistema operacional é um programa que adiciona um conjunto
de novas instruções e funcionalidades, além daquelas suportadas pelo
nível ISA.
O conjunto de instruções do nível do sistema operacional é aquele que
está disponível para os programadores de aplicações. Nele estão
presentes praticamente todas as instruções do nível ISA, bem como um
novo conjunto de instruções que o sistema operacional adiciona,
conhecidas como chamadas de sistema.
Uma chamada de sistema ativa um determinado serviço prestado pelo
sistema operacional ao nível da aplicação, como por exemplo, a leitura de
um dado de um arquivo.
O nível do sistema operacional é sempre interpretado, ou seja,
quando um programa do usuário executa uma instrução desse nível, o
sistema operacional executa essa instrução passo a passo.
Outra funcionalidade importante do nível do sistema operacional é a
abstração do hardware. A parte física de uma máquina ( hardware ) pode
ser bem diferente do de outra máquina. Os sinais digitais necessários para
executar uma mesma tarefa podem ser radicalmente diferentes de um
modelo de computador para, ou seja, cada dispositivo pode trabalhar com
uma linguagem específica. Entretanto, deve ser possível que um mesmo
programa rode adequadamente em dois computadores com diferentes
estruturas de hardware.
É aí que entra o Sistema Operacional. Ele é um programa especial
capaz de gerenciar o funcionamento de todos os outros, realizando a
interpretação entre a linguagem genérica do software para a linguagem
mais específica do hardware.
Por exemplo, todos os programas compatíveis com um dado sistema
operacional podem invocar as mesmas instruções na forma de chamadas
de sistema para escrever um arquivo em um disco. Cabe ao sistema
operacional interpretar essa chamada de sistema e executá-la,
comunicando-se com o hardware onde o arquivo será gravado. Esse
hardware pode ser um disco rígido ou um pen-drive, por exemplo. Ambos
possuem uma tecnologia totalmente diferente, e cabe ao sistema
operacional ser capaz de se comunicar adequadamente com o dispositivo
em questão.
Por exemplo, no caso de dispositivos plug and play com interface de
comunicação USB como um pen-drive ou HD externo, quando são
plugados em um computador pela primeira vez, surge uma mensagem de
instalação do driver do dispositivo. Instalar o driver de um novo periférico
é a maneira do sistema operacional "aprender" uma nova linguagem, para
comunicar-se com um novo dispositivo.
O sistema operacional também encarrega-se do gerenciamento de
processos e a hierarquia de acesso dos processos em execução. Pode-se
ter um sistema operacional multitarefa, com cada processo em execução
por uma fatia de tempo, determinado pelo s.o.. Os processos também não
podem ter acesso a qualquer endereço de memória, pois dessa maneira
poderiam provocar pane em outros processos ou no funcionamento do
próprio sistema operacional.
O acesso à memória é restrito, pois processos comuns são executados
com o microprocessador no modo protegido.
Aspectos importantes relativos aos sistemas operacionais: memória
virtual, entrada/saída de arquivos e processamento paralelo.
Memória virtual é uma técnica implementada na maioria dos sistemas
operacionais para fazer com que a máquina pareça ter mais memória do
que na verdade ela tem.
Uma maneira de se organizar a memória virtual é usar uma abstração
denominada arquivo. Para o sistema operacional um arquivo nada mais é
do que uma sequência de bytes.
A E/S de arquivos é feita por chamadas do sistema operacional para
abertura, leitura, escrita e fechamento de arquivos.
Em um sistema computacional com mais de um processador, cada um dos
vários processos cooperantes que rodam nele poderá ter seu próprio
processador, de modo a permitir que esses processos avancem
simultaneamente. Por outro lado, se houver apenas um processador
disponível, o efeito do processamento paralelo poderá ser simulado,
fazendo com que o processador se dedique a um processo de cada vez,
por curto espaço de tempo, ou seja, o processador pode ser compartilhado
por vários processos.

O nível 4 é denominado nível de linguagem de montagem ( assembly


language ). Neste nível ocorre a tradução do programa original, expresso
na linguagem fonte para uma outra linguagem denominada linguagem
alvo.
Dependendo da relação entre a linguagem fonte e a linguagem alvo, os
tradutores podem ser divididos em dois grupos. Quando a linguagem fonte
for essencialmente uma representação simbólica para uma linguagem de
máquina numérica, o tradutor é chamado de montador ( assembler ) e a
linguagem fonte é chamada de linguagem de montagem ( assembly ). Na
linguagem de montagem, as instruções do nível ISA são representadas
por mnemônicos, mais fáceis de serem interpretados do seres humanos
do que sequências puras de bits.
Por outro lado, quando a linguagem fonte for uma linguagem de alto
nível e a linguagem alvo for uma linguagem de máquina numérica ou uma
representação simbólica desta linguagem, o tradutor é chamado de
compilador.
Uma linguagem de montagem pura é aquela na qual cada comando
produz exatamente uma instrução de máquina, ou seja, existe uma
correspondência um para um entre as instruções de máquina e os
comandos de um programa expresso em linguagem do montador.
As linguagens do nível 5 são projetadas para serem usadas por
programadores de aplicação, com algum problema a ser resolvido. Tais
linguagens são conhecidas como linguagens de alto nível. Os programas
escritos nestas linguagens são convertidos para os níveis 3 ou 4 por
tradutores conhecidos como compiladores.
Exemplo de um programa simples para imprimir uma mensagem na
tela:

Usando uma linguagem do nível 5 ( linguagem C ):

#include <stdio.h>

int main( int argc, char *argv[] )

printf( "Olá, mundo!" );

return 0;

E na linguagem do nível 4 ( assembly ou lingugem de montagem para


processadores da família x86 com sistema operacional Windows ou MS-
DOS ):

.model tiny

.data

DB frase 'Olá, mundo!", $

.code

org 0100h

mov dx, frase

mov ah, 9

int 21h

mov ah, 4ch

int 21h
.end

Um outro exemplo de trecho de código escrito em assembly para


processadores da família x86 ( presente em computadores pessoais ).

; ------------- Início da manipulação dos dados do arquivo encontrado

; ----- Abre o arquivo, obtendo o Handle

mov dx, 9eh ; Endereço onde está o nome do arquivo


encontrado.

mov ax, 3d02h ; Abre o arquivo para leitura-escrita.


int 21h

; O handle do arquivo foi obtido em AX mas


deve
mov bx, ax ; ser movido para BX para as próximas
funções.

; ----- Obtém a data e hora da última alteração do arquivo.

mov ah, 57h


xor al, al ; mov al, 0
int 21h

lea di, [offset Horario + bp]


mov ax, cx
stosw

lea di, [offset Data + bp]


mov ax, dx
stosw

; ----- Salva a parte do arquivo que inevitavelmente será


alterada,
; lendo e armazenando os primeiros bytes do arquivo a
ser
; modificado. Para tanto o início do futuro hospedeiro
deve
; ser lido e os primeiros bytes armazenados em Backup.

lea dx, [offset Backup + bp]; Buffer onde os dados serão


gravados.
mov cx, bytes
mov ah, 3fh
int 21h

; ----- Descobre se o programa realmente é um .COM


internamente

lea si, [offset Backup + bp]


lodsw
cmp ax, 'ZM' ; Equivale a comparar com 'MZ'
je Proximo1

A linguagem assembly ainda é utilizada principalmente na programação


de microcontroladores, que são computadores completos em um
único chip, já que possuem processador, memória e periféricos
embutidos. Circuitos eletrônicos com microcontroladores fazem parte
dos chamados sistemas embarcados, que são sistemas que possuem
microcontroladores que conferem uma certa "inteligência" a outros
dispositivos, tais como eletrodomésticos, alarmes, fontes de energia,
cancelas eletrônicas, brinquedos, etc.

A seguir um exemplo de trecho de código escrito em assembly para um


microcontrolador da família 8051.

ORG 0000h ; VETOR DE RESET.

SJMP STARTUP ; DESVIA PARA O CÓDIGO DE INICIALIZAÇÃO.

ORG 0003h ; ENDEREÇO DA INT0.


NOP
RETI

ORG 000Bh ; ENDEREÇO DO TIMER0


NOP
RETI

ORG 0013h ; ENDEREÇO DA INT1.


NOP
RETI

ORG 001Bh ; ENDEREÇO DO TIMER1.


NOP
RETI

ORG 0023h ; ENDEREÇO DA INTERRUPÇÃO SERIAL.

NOP

SJMP SERIALISR ; DESVIA PARA A ISR DA SERIAL.

RETI

STARTUP: ; CÓDIGO DE INICIALIZAÇÃO.

MOV P1, #00000000b ; PORT P1 INICIALMENTE ZERADO.

MOV TMOD, #00100000b ; TIMER1 EM MODO 2 : 8 BITS COM


AUTO-RELOAD.

MOV TH1, #0FDh ; PRESET VALUE DO MODO 2 DO TIMER1.


; BAUD-RATE= 9600 bps
MOV TL1, #0h ; CONTADOR INICIALMENTE EM ZERO.

SETB TR1 ; LIGA O TIMER1.


MOV SCON, #01010000b ; SERIAL NO MODO 1, COM BIT REN
HABILITADO.

MOV PCON, #00000000b ; SMOD= 0. SEM DOBRAR A FREQUÊNCIA


DA SERIAL.

MOV IP, #00010000b ; INTERRUPÇÃO SERIAL COM ALTA


PRIORIDADE.

MOV IE, #10010000b ; INTERRUPÇÃO SERIAL HABILITADA. COM


EA= 1.

MAINLOOP: ; LAÇO PRINCIPAL DO PROGRAMA.

NOP

SJMP MAINLOOP ; LAÇO INFINITO.

SERIALISR: ; ROTINA DE TRATAMENTO DA INTERRUPÇÃO


SERIAL.

NOP

MOV P1, SBUF ; MOVE O VALOR DO BUFFER SERIAL PARA O PORT


P1.

CLR RI ; RESSETA O FLAG DA INTERRUPÇÃO DA SERIAL.

RETI ; RETORNO DA INTERRUPÇÃO.

END ; FIM DO PROGRAMA.

A seguir, um outro exemplo de programação em assembly: um trecho


de código para um microcontrolador da família HC908Q da Freescale:

( Repare que o que é escrito à direita do ponto-e-vírgula são


comentários que servem apenas para o programador ter mais facilidade
para entender o programa durante a edição do código, e não faz parte
do código em linguagem de máquina gerado posteriormente ).

SHOWDISPLAY:

MOV ,X+, DIGITO ; MOVE O VALOR APONTADO POR X PARA


A VARIÁVEL DIGITO, INCREMENTANDO X EM SEGUIDA.
STX XBKP ; SALVA O CONTEÚDO DE X EM XBKP,
POIS ESSE REGISTRADOR SERÁ
ALTERADO.

LDA #DISPLAY ; CARREGA O ENDEREÇO INICIAL DO


VETOR DE CÓDIGO DOS DÍGITOS PARA DISPLAY.
ADD DIGITO ; ADICIONA O VALOR DO DÍGITO, QUE
FUNCIONA COMO ÍNDICE.

TAX ; MOVE O RESULTADO, NO ACUMULADOR,


PARA O REGISTRADOR APONTADOR, X.
MOV ,X+, PTB ; MOVE O CONTEÚDO DO ENDEREÇO
APONTADO POR X PARA O PORT PTB, EXIBINDO O DÍGITO NO
DISPLAY.

RTS ; RETORNO DA SUB-ROTINA.

TRATA_TIM: ; ROTINA DE TRATAMENTO DA


INTERRUPÇÃO DO TIMER ( TIM ).

LDA CONTADOR ; CARREGA O CONTEÚDO DA VARIÁVEL


CONTADOR NO REGISTRADOR ACUMULADOR.
BEQ PROSSEGUIR ; DESVIA PARA PROSSEGUIR, CASO O
VALOR SEJA IGUAL A ZERO.

DEC CONTADOR ; SENÃO, DECREMENTA O CONTADOR.

BCLR 7, TSC ; RESSETA O FLAG DA INTERRUPÇÃO.


T0F= 0.

RTI ; RETORNA DA ROTINA DE INTERRUPÇÃO.

PROSSEGUIR:

BCLR 7, TSC ; RESSETA O FLAG DA INTERRUPÇÃO.


TOF= 0.

LDA #$01 ; CARREGA A MÁSCARA 00000001 NO


ACUMULADOR.
EOR PTA ; REALIZA UMA OPERAÇÃO XOR, QUE
INVERTE APENAS O BIT 0.
STA PTA ; CARREGA O RESULTADO NO PTA, PARA
COMUTAR O LED.

LDA TEMPO1 ; CARREGA O CONTEÚDO DE TEMPO1 NO


ACUMULADOR.
CMP #2 ; COMPARA O VALOR COM 2.

BHI NAO_APAGAR ; SE MAIOR QUE 2, DESVIA PARA


NAO_APAGAR.

CLR PTB ; APAGA O DISPLAY, TEMPORARIAMENTE,


ANTES DO DÍGITO SEGUINTE.

NAO_APAGAR:

DBNZ TEMPO1, NO_CHANGE ; DECREMENTA TEMPO1, DESVIANDO


PARA NO_CHANGE SE DIFERENTE DE ZERO.

MOV #6, TEMPO1 ; REINICIA TEMPO1.

Para exemplificar como a linguagem assembly muda de acordo com a


arquitetura do processador, segue um outro trecho de código escrito em
assebly.
Dessa vez para um microcontrolador da família PIC16:

RST CODE 0x0000 ; VETOR DE RESET

GOTO STARTUP ; DESVIA PARA O


CÓDIGO DE INICIALIZAÇÃO.

ISR CODE 0x00004 ; VETOR DE


INTERRUPÇÃO.

MOVWF W_TEMP ; SALVA A IMAGEM DOS


REGISTRADORES PRINCIPAIS.
SWAPF STATUS, W
BCF STATUS, RP0
MOVWF STATUS_TEMP

BTFSS INTCON, T0IF ; TESTA SE A


INTERRUPÇÃO FOI GERADA PELO TIMER0.
GOTO RESTORE_REGS ;

BCF INTCON, T0IF ; RESSETA BIT QUE


SINALIZA A INTERRUPÇÃO.

INCF DELAY_COUNT, F ; INCREMENTA O


CONTADOR DE ATRASO.
MOVLW D'3'
SUBWF DELAY_COUNT, W ; APÓS 3 ITERAÇÕES
VOLTA.
BNZ RESTORE_REGS ; ENQUANTO
DELAY_COUNT != 3, RETORNA DA INTERRUPÇÃO.

CLRF DELAY_COUNT ; RESSETA O CONTADOR


DELAY_COUNT.

INCF CONTADOR, F ; INCREMENTA O


CONTADOR. ( CONTADOR= CONTADOR + 1.)

MOVLW D'100' ; SE CONTADOR ==


100, CONTADOR= 0.
SUBWF CONTADOR, W
BNC RESTORE_REGS
CLRF CONTADOR

RESTORE_REGS ; RESTAURA OS
REGISTRADORES WREG E STATUS.

SWAPF STATUS_TEMP, W
MOVWF STATUS
SWAPF W_TEMP, F
SWAPF W_TEMP, W

RETFIE ; RETORNA DA
INTERRUPÇÃO.

STARTUP CODE ; CÓDIGO DE


INICIALIZAÇÃO.
STARTUP

BANK1

MOVLW B'00000111' ; TIMER0 COM PRESCALER


1:128.
MOVWF OPTION_REG

CLRF TRISB ; TODOS OS PINOS DO PORTB


FUNCIONAM COMO SAÍDAS.

BANK0

CLRF DELAY_COUNT ; INICIALIZA DELAY_COUNT


ZERADO.

MOVLW B'10100000' ; HABILITA A CHAVE


GERAL DE INTERRUPÇÕES E A INT.
MOVWF INTCON ; DO TIMER0.

CLRF CONTADOR ; RESSETA O CONTADOR.

MOVLW D'10' ; DIVISOR= 10.


MOVWF DIVISOR

CLRF PORTB ; RESSETA O PORTB.

MAINLOOP

MOVF CONTADOR, W ; DIVIDENDO= CONTADOR.


MOVWF DIVIDENDO

CALL DIVISAO ; CHAMA A ROTINA DE


DIVISÃO.

SWAPF QUOCIENTE, W ; CARREGA EM WREG


QUOCIENTE COM OS NIBBLES TROCADOS.
IORWF RESTO, W ; ATRIBUI RESTO AO
NIBBLE MENOS SIGNIFICATIVO.
MOVWF PORTB ; CONTEÚDO NA SAÍDA DO
PORTB.

GOTO MAINLOOP ; PERMANECE NO LAÇO


MAINLOOP.

END ; FIM DO PROGRAMA.

Naturalmente, é bem mais fácil programar em assembly do que


diretamente em código de linguagem de máquina ( os primeiros
computadores eram programados em linguagem de máquina binária ! ).

Entretanto, mais fácil é programar em linguagens de médio e alto nível,


tais como as linguagens descendentes de Basic, C e Pascal. Essas
linguagens estão estruturadas de uma forma mais próxima da descrição
de um algoritmo, e mais distantes da linguagem da máquina.
É fácil perceber que, quanto mais alto o nível da linguagem mais fácil é o
aprendizado de programação, pois a escrita e leitura do código é mais
intuitiva e parecida com a linguagem humana.

Além disso, uma linguagem de alto nível é mais genérica, podendo ser
traduzida para a linguagem de máquina de diversos tipos de
microprocessadores.

Já a linguagem de máquina ( de baixo nível ) é específica de uma


determinada família de microprocessadores.

Você também pode gostar