Calc

Posted on March 9, 2010, 10:29 pm UTC by Iago (about 1 year ago)

Code (highlighted for ASM)

  1. [bits 16] ; Vamos utilizar um assembly de 16 bits, para poder usar as interrupções.
  2. [org 0x100] ; Para usar um 16 bits, temos que iniciar no endereço 0x100 da memória.
  3.  
  4. section .data
  5. ; Dados inicializados.
  6. prompt dw "O que voce deseja?", 0x0A, 0x0D
  7. dw "1. Somar", 0x0A, 0x0D
  8. dw "2. Subtrair", 0x0A, 0x0D
  9. dw "3. Multiplicar", 0x0A, 0x0D
  10. dw "4. Dividir", 0x0A, 0x0D, 0x24
  11. first  dw "Insira um numero: ", 0x24
  12. secnd  dw "Voce inseriu: "
  13. char   dq 0
  14. err    dw "Nao utilize teclas virtuais como F1!", 0x24
  15. err2   dw "Insira apenas numeros!", 0x24
  16. section .text     ; Todo o código.
  17. global main       ; Dizemos que a main pode ser chamada por qualquer programa.
  18. main:             ; A "label" main, "label" significa rótulo.
  19. call cls          ; Chamamos a label cls, para limpar a tela.
  20. mov dx, prompt    ; Movemos o valor do endereço da variavel prompt para o registrador dx.
  21. mov ax, 0x0900
  22. int 0x21
  23. xor ax, ax
  24. int 0x16
  25. sub al, 0x30
  26. test al, al
  27. jz mm
  28. cmp al, 0x09
  29. jg mm
  30. cmp al, 0x01
  31. je sum
  32. cmp     al, 0x02
  33. je sbt
  34. cmp     al, 0x03
  35. je mll
  36. cmp al, 0x04
  37. je dvv
  38. mov dx, first     ; Movemos o valor do endereço da variável first para o registrador dx.
  39. mov ax, 0x0900    ; Movemos o valor 09 para o high level do registrador ax, o ah.
  40. int 0x21          ; Interrupção 21 do processador. A int 21 é a int para funções do DOS.
  41. xor di, di        ; Zeramos o valor de di, isso é um truque, bastar analizar o que o XOR faz.
  42. call get          ; Chamamos a label get, para pegar todos os caracteres até que o
  43.                   ; 0x0d <enter> seja pressionado.
  44. call cls          ; Novamente chamamos a label cls para limpar a tela.
  45. mov dx, secnd     ; Movemos o valor do endereço da variável secnd para o registrador dx.
  46. mov ax, 0x0900    ; Movemons o valor 09 para o high level novamente!
  47. int 0x21          ; A int 21 (não diga).
  48. jmp     quit          ; Saltamos para o fim do script chamando a label quit para
  49.                   ; terminar o programa.
  50.  
  51. get:              ; Label get, encarregada de pegar os caracteres pressionados pelo
  52.                   ; usuário até que o <enter> seja pressionado e assim liberando o
  53.                   ; "loop"
  54. xor     ax, ax        ; Zerando o registrador ax
  55. int 0x16          ; A int 16 do processador. A int 16 é encarregada do teclado.
  56. test al, al       ; TESTando o al, o "test" é igual o "and" só que não altera o
  57.                   ; valor do primeiro parâmetro (al)!
  58. jz zero           ; Se for zero vai pra label zero.
  59. cmp al, 0x0D      ; Compara o registrador al com o 0x0D (enter), para sair do "loop".
  60. je .finish        ; Se for <enter> pula para o sub-label finish.
  61. sub al, 0x30      ; Se não for, subtrai 30 do registrador al e o resultado vai para o
  62.                   ; registrador al!
  63. test al, al       ; Compara o registrador al com 1.
  64. jz mm             ; Se for menor (jump if less) então pula para a label mm.
  65. cmp     al, 0x09      ; Compara o registrador al com 9.
  66. jg mm                     ; Se for maior (jump if greater) então pula para a label mm.
  67. mov     [char+di], al ; Move o valor de al para o endereço "char+di", é adicionado de di
  68.                   ; para nunca sobreescrever o caractere anterior.
  69. inc di            ; Adiciona 1 ao registrador di.
  70. jmp     get           ; Pula para o get, assim fazendo o "loop".
  71. .finish:
  72. mov al, 0x24      ; Move o valor 0x24 ($) para o registrador al, o "$" é usado para
  73.                   ; Finalizar uma string.
  74. mov [char+di], al ; O mesmo procedimento acima.
  75. ret               ; Retorna para depois de ser chamado.
  76.  
  77. mm:
  78. mov dx, err2
  79. mov ax, 0x0900
  80. int 0x21
  81. jmp get
  82.  
  83. zero:             ; Label zero
  84. call cls          ; Chama a label cls
  85. mov dx, err       ; Move o valor do endereço da variável err para o registrador dx
  86. mov ax, 0x0900    ; Movemons o valor 09 para o high level novamente!
  87. int 0x21          ; A int 21...
  88. jmp main          ; Pulamos para o começo do código, a label main.
  89.  
  90. cls:              ; Label cls
  91. mov ax, 0x0600    ; Movemons o valor 06 para o high level do registrador ax, o ah.
  92. mov bh, 0x07      ; Aqui é o atributo para cada byte da janela do prompt, o atributo
  93.                   ; 7 é a cor do texto, no caso de eu inserir A o texto irá ser verde
  94. xor cx, cx        ; Zerando o cx
  95. mov dx, 0x2479    ; Movemos o valor 2479h para o registrador dx, a janela padrão do
  96.                   ; prompt tem 80x25 de tamanho, que vai de 0x0 até 79x24, isso porque
  97.                   ; o zero não é ignorado, então o 2479 é o inverso de 79x24, foi
  98.                   ; usado para limpar toda a tela.
  99. int 0x10          ; A int 10, responsável pelo vídeo.
  100. mov ax, 0x0200    ; ...
  101. mov bh, 0x00      ; ...
  102. xor dx, dx        ; ...
  103. int 0x10          ; A int 10, responsável pelo vídeo.
  104. ret               ; Retorna para depois de ser chamado.
  105.  
  106. quit:             ; Label quit
  107. int 0x20          ; Int 20 é usada para sair do programa