Calc
Posted on March 9, 2010, 10:29 pm UTC by Iago (about 1 year ago)Code (highlighted for ASM)
- [bits 16] ; Vamos utilizar um assembly de 16 bits, para poder usar as interrupções.
- [org 0x100] ; Para usar um 16 bits, temos que iniciar no endereço 0x100 da memória.
- section .data
- ; Dados inicializados.
- prompt dw "O que voce deseja?", 0x0A, 0x0D
- dw "1. Somar", 0x0A, 0x0D
- dw "2. Subtrair", 0x0A, 0x0D
- dw "3. Multiplicar", 0x0A, 0x0D
- dw "4. Dividir", 0x0A, 0x0D, 0x24
- first dw "Insira um numero: ", 0x24
- secnd dw "Voce inseriu: "
- char dq 0
- err dw "Nao utilize teclas virtuais como F1!", 0x24
- err2 dw "Insira apenas numeros!", 0x24
- section .text ; Todo o código.
- global main ; Dizemos que a main pode ser chamada por qualquer programa.
- main: ; A "label" main, "label" significa rótulo.
- call cls ; Chamamos a label cls, para limpar a tela.
- mov dx, prompt ; Movemos o valor do endereço da variavel prompt para o registrador dx.
- mov ax, 0x0900
- int 0x21
- xor ax, ax
- int 0x16
- sub al, 0x30
- test al, al
- jz mm
- cmp al, 0x09
- jg mm
- cmp al, 0x01
- je sum
- cmp al, 0x02
- je sbt
- cmp al, 0x03
- je mll
- cmp al, 0x04
- je dvv
- mov dx, first ; Movemos o valor do endereço da variável first para o registrador dx.
- mov ax, 0x0900 ; Movemos o valor 09 para o high level do registrador ax, o ah.
- int 0x21 ; Interrupção 21 do processador. A int 21 é a int para funções do DOS.
- xor di, di ; Zeramos o valor de di, isso é um truque, bastar analizar o que o XOR faz.
- call get ; Chamamos a label get, para pegar todos os caracteres até que o
- ; 0x0d <enter> seja pressionado.
- call cls ; Novamente chamamos a label cls para limpar a tela.
- mov dx, secnd ; Movemos o valor do endereço da variável secnd para o registrador dx.
- mov ax, 0x0900 ; Movemons o valor 09 para o high level novamente!
- int 0x21 ; A int 21 (não diga).
- jmp quit ; Saltamos para o fim do script chamando a label quit para
- ; terminar o programa.
- get: ; Label get, encarregada de pegar os caracteres pressionados pelo
- ; usuário até que o <enter> seja pressionado e assim liberando o
- ; "loop"
- xor ax, ax ; Zerando o registrador ax
- int 0x16 ; A int 16 do processador. A int 16 é encarregada do teclado.
- test al, al ; TESTando o al, o "test" é igual o "and" só que não altera o
- ; valor do primeiro parâmetro (al)!
- jz zero ; Se for zero vai pra label zero.
- cmp al, 0x0D ; Compara o registrador al com o 0x0D (enter), para sair do "loop".
- je .finish ; Se for <enter> pula para o sub-label finish.
- sub al, 0x30 ; Se não for, subtrai 30 do registrador al e o resultado vai para o
- ; registrador al!
- test al, al ; Compara o registrador al com 1.
- jz mm ; Se for menor (jump if less) então pula para a label mm.
- cmp al, 0x09 ; Compara o registrador al com 9.
- jg mm ; Se for maior (jump if greater) então pula para a label mm.
- mov [char+di], al ; Move o valor de al para o endereço "char+di", é adicionado de di
- ; para nunca sobreescrever o caractere anterior.
- inc di ; Adiciona 1 ao registrador di.
- jmp get ; Pula para o get, assim fazendo o "loop".
- .finish:
- mov al, 0x24 ; Move o valor 0x24 ($) para o registrador al, o "$" é usado para
- ; Finalizar uma string.
- mov [char+di], al ; O mesmo procedimento acima.
- ret ; Retorna para depois de ser chamado.
- mm:
- mov dx, err2
- mov ax, 0x0900
- int 0x21
- jmp get
- zero: ; Label zero
- call cls ; Chama a label cls
- mov dx, err ; Move o valor do endereço da variável err para o registrador dx
- mov ax, 0x0900 ; Movemons o valor 09 para o high level novamente!
- int 0x21 ; A int 21...
- jmp main ; Pulamos para o começo do código, a label main.
- cls: ; Label cls
- mov ax, 0x0600 ; Movemons o valor 06 para o high level do registrador ax, o ah.
- mov bh, 0x07 ; Aqui é o atributo para cada byte da janela do prompt, o atributo
- ; 7 é a cor do texto, no caso de eu inserir A o texto irá ser verde
- xor cx, cx ; Zerando o cx
- mov dx, 0x2479 ; Movemos o valor 2479h para o registrador dx, a janela padrão do
- ; prompt tem 80x25 de tamanho, que vai de 0x0 até 79x24, isso porque
- ; o zero não é ignorado, então o 2479 é o inverso de 79x24, foi
- ; usado para limpar toda a tela.
- int 0x10 ; A int 10, responsável pelo vídeo.
- mov ax, 0x0200 ; ...
- mov bh, 0x00 ; ...
- xor dx, dx ; ...
- int 0x10 ; A int 10, responsável pelo vídeo.
- ret ; Retorna para depois de ser chamado.
- quit: ; Label quit
- int 0x20 ; Int 20 é usada para sair do programa