lunes, 15 de julio de 2013

Número perfecto utilizando macros con Include

Hola de nuevo, en esta ocación les presento el código que verifica si un número es perfecto utilizando macros desde un archivo externo para ahorrar código.

Los números perfectos es la suma de todos los números antecesores de ese número que divididos entre el número original su residuo sea 0, y que la suma dada sea igual al número original, así el número 6 es un número perfecto porque sus divisores con residuo 0 son 1, 2 y 3; y 6=1+2+3. Los siguientes números perfectos son 28, 496, 8128.

La lógica del programa: Dividir el número dado desde 1 hasta n y verificar su residuo, en caso de ser 0 se sumará a una variable, caso contrario no hará nada.

Limitaciones del programa: Solo funciona con los números del 0 al 9.

La utilización de macros en un archivo externo es para la utilización y ahorro de código, en nuestro ejemplo utilizaremos un archivo llamado macros.asm con el código de las macros, en este archivo tendremos 2 macros, uno para imprimir cadenas y el otro para pedir un número. La ventaja de hacer este archivo macros.asm es que lo podemos utilizar en cualquier otro programa de ensamblador.

Para poder llamar el archivo de macros.asm en nuestro código ensamblador hacemos uso de la instrucción include, su sintaxis es simple:

include direcciónArchivo/nombreArchivo.txt


El archivo macros.asm
 imprime macro cadena
  mov ax,@data
  mov ds,ax
  mov ah,09h
  mov dx,offset cadena
  int 21h
endm

pedir macro  ;Pide el numero perfecto
  mov ah,01h
  int 21h
  sub ah,01h
  sub al,30h
endm

Código del programa perfecto.asm:

.model small
.stack 64
.data
  msj db 0ah,0dh, 'Digita un numero', '$'
  msj2 db 0ah,0dh, 'Es perfecto', '$'
  msj3 db 0ah,0dh, 'No es perfecto', '$'
  vec db 10 dup (0)
  aux db 0
  sum db 0
.code
inicio:
 include macros.asm
;Llamamos al archivo macros.asm y podemos hacer uso de su código, mi archivo
;macros.asm y perfecto.asm estan en la misma carpeta BIN de MASM611 cuando es así no se pone la ;dirección del archivo, caso contrario hay que especificar la dirección.

  imprime msj  ;llamada al macro para imprimir el mensaje 1
  pedir  ;Llamada al macro para pedir un número
  mov cx,ax  ;respaldamos el número pedido en cx
  mov aux,cl  ;Movemos el mismo número a una variable auxiliar
  mov bl,00h

;Empezamos a dividir desde 1
operacion:
  inc bx 
  mov cl,aux ;Regresamos el número respaldado en la variable auxiliar
  mov ax,cx ;como la división se hacen sobre AX mandamos el número a AX.
aad  ;ajuste ascii para division
   mov cx,0000 ;limpiamos CX
  mov dx,0000
 
div bx ;se divide AX/BX, ax contiene el número digitado, bx es nuestro contador que va de 1 a n
  cmp dx,00h  ;Comparo DX con 0, ya que DX contiene el residuo.
  ja operacion ;si es mayor a 0 repite operacion
  jb operacion ;si es menor a 0 repita operacion
  je compara ;si es igual a 0 salta a compara

compara:  ;esta etiqueta compara si bx ya llego a ser igual al número original
  cmp aux,bl
  je cmpperfecto ;si es igual pasa a comparar si es perfecto
  ja suma ;si no es igual pasa a suma
  jb suma
 
suma:  ;esta etiqueta suma el valor de bl a nuestra variable sum
  add sum,bl
  jmp operacion  ;se repite operacion

cmpperfecto:  ;Etiqueta compara el valor sumado a
  mov al,sum
  cmp al,aux
  je perfecto
  ja noperfecto
  jb noperfecto

perfecto: ;Solo imprime que es perfecto
 imprime msj2
jmp salir

noperfecto: ;Solo imprime que NO es perfecto
  imprime msj3
  jmp salir

salir:
mov ah,04ch
int 21h
end

 Programa en ejecución:


No hay comentarios:

Publicar un comentario