![Hola :hola:](https://solocodigo.com/Smileys/solocodigo/hola.gif)
Muchas gracias... mi programita a quedado re chulo
![Tongue :P](https://solocodigo.com/Smileys/solocodigo/tongue.gif)
os muestro aquì :
;******************************************************************************
; Nombre del programa : CONTANDO.ASM
; Objetivo : Realizar manejo del puerto
;******************************************************************************
; COMANDO DE ENSAMBLE : Tasm CONTANDO.ASM;
; COMANDO DE ENLACE : Tlink CONTANDO;
; COMANDO DE EJECUCION : CONTANDO [Enter]
;******************************************************************************
;------------------------------------------------------------------------------
; Define el MODELO DE MEMORIA
;------------------------------------------------------------------------------
.MODEL SMALL
;------------------------------------------------------------------------------
; Define el area DE DATOS
;------------------------------------------------------------------------------
.Data
ErrorCAP DB 0 ; Bandera de error en la captura de las cantidades
Cantidad DB 0 ; La cantidad sobre la que se opera. Si es 0 se opera
; sobre la cantidad 1, si es 1 se opera sobre la
; cantidad 2.
CantUnoR DW 0 ; Variable que guarda la cantidad 1 convertida a binario.
CantDosR DW 0 ; Variable que guarda la cantidad 2 convertida a binario.
CantUnoN DB 4,0,4 DUP(?) ; Variable que almacena la cantidad 1
CantDosN DB 4,0,4 DUP(?) ; Variable que almacena la cantidad 2
Funcion DB 0 ; Variable que guarda la funcion a realizar
Resulta DB 13,10,13,10,'NuMeRoS: $'
ResultaR DB 11 DUP('?')
Mensaje DB 'Bienvenidos a Contando,... Al fin terminamos banda GsOiD'
DB 13,10,13,10,'$'
Pregunta DB 13,10,13,10,'DIGITE:',13,10,13,10
DB ' (1) para Incrementar.',13,10
DB ' (2) para Decrementar.',13,10
DB ' (3) para Autor.',13,10
DB ' (4) para TERMINAR.',13,10,'$'
Error DB 7,7,7,13,10,'ERROR : en la seleccion de las opciones.'
DB 13,10,13,10,'$'
Error1 DB 7,7,7,13,10,'ERROR : digito INVALIDO en CANTIDAD 1.'
DB 13,10,13,10,'$'
Error2 DB 7,7,7,13,10,'ERROR : digito INVALIDO en CANTIDAD 2.'
DB 13,10,13,10,'$'
Error3 DB 7,7,7,13,10,'ERROR : cantidad fuera de RANGO ( 255).'
DB ' !!!.'
DB 13,10,13,10,'$'
CantunoM DB 13,10,13,10,'DiGiTe CaNtIdAd (debe ser < a 256)'
DB ' : $'
CantDosM DB 13,10,13,10,'NúMeRo de Inc o Dec'
DB ' : $'
DB 13,10,13,10
Autores DB 'Code by EsToIcA GsOiD ! ',13,10
DB 13,10,13,10,'$'
;------------------------------------------------------------------------------
; TABLA DE POTENCIAS USADA PARA CONVERTIR EL RESULTADO BINARIO DE LA
; OPERACION EN FORMATO ASCII.
;------------------------------------------------------------------------------
Potencia DW 0001h, 000ah, 0064h ;, 03E8h, 2710h
;------------------------------------------------------------------------------
; Define el area del Stack
;------------------------------------------------------------------------------
.STACK
;------------------------------------------------------------------------------
; Define el area de codigo
;------------------------------------------------------------------------------
.CODE ; Area de codigo
;------------------------------------------------------------------------------
; Inicia programa
;------------------------------------------------------------------------------
Empieza: ; Etiqueta de comienzo de programa
;------------------------------------------------------------------------------
; BORRA LA PANTALLA CAMBIANDO LA MODALIDAD DE VIDEO.
;------------------------------------------------------------------------------
Mov Ah, 0Fh ; Obtiene la modalidad de video actual
Int 10h
Mov Ah, 0 ; Cambia la modalidad de video que se obtuvo
Int 10h
Mov Ax,@Data ; Inicializa DS con la direccion de @Data
Mov Ds, Ax
Mov Dx, Offset Mensaje ; Despliega el mensaje de bienvenida
Call Imprime
Mov Si, Offset ResultaR ; Inicializa la variable ResultaR
Add Si, 11
Mov Al, '$'
Mov [Si], Al
;------------------------------------------------------------------------------
; SE DESPLIEGA EL MENU DE OPCIONES A ELEGIR.
;------------------------------------------------------------------------------
OTRA:
Mov Dx, Offset Pregunta ; Despliega menu de opciones
Call Imprime
Call ObtenTecla ; Espera a que el usuario seleccione la
; funcion a realizar (1 a 4)
Cmp Al, 49 ; La seleccion del usuario es mayor o igual
Jae SIGUE ; a 1 ?.
Mov Dx, Offset Error ; NO, despliega mensaje de error
Call Imprime
Jmp OTRA
SIGUE:
Cmp Al, 52 ; La seleccion del usuario es menor o igual
Jbe TODOBIEN ; a 4?.
Mov Dx, Offset Error ; NO, despliega mensaje de error
Call Imprime
Jmp OTRA
TODOBIEN:
Cmp Al, 52
Jnz CHECATODO
Jmp FUNCION4
CHECATODO:
Mov Funcion, Al ; Guarda la funcion a realizar
;------------------------------------------------------------------------------
; SE CAPTURAN LAS CANTIDADES Y SE GUARDAN EN SUS RESPECTIVAS VARIABLES PARA
; PODER TRABAJAR SOBRE ELLAS MAS ADELANTE.
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; CAPTURA PRIMER CANTIDAD.
;------------------------------------------------------------------------------
CAPCANT01:
Mov Dx, Offset CantUnoM ; Mensaje de captura de cantidad 1
Call Imprime
Mov Ah, 0Ah ; Captura la cantidad (hasta 3 digitos)
Mov Dx, Offset CantUnoN
Int 21h
Mov ErrorCAP, 0 ; Supone que no hay errores y que se esta
Mov Cantidad, 0 ; operando sobre la cantidad 1.
Call ConvNUM ; Convierte cantidad 1 a binario
Cmp ErrorCAP, 1 ; ¨Hubo error?
Jz CAPCANT01 ; S¡, regresa a la captura
Mov CantUnoR, Bx ; Guarda resultado de conversion
cmp CantUnoR,255
jg CAPCANT01
;------------------------------------------------------------------------------
; CAPTURA SEGUNDA CANTIDAD.
;------------------------------------------------------------------------------
CAPCANT02:
Mov ErrorCAP, 0 ; Supone que no hay error
Mov Cantidad, 1 ; Indica a ConvNUM que es la segunda cantidad
Mov Dx, Offset CantDosM ; Mensaje de captura de cantidad 2
Call Imprime
Mov Ah, 0Ah ; Captura la segunda cantidad
Mov Dx, Offset CantDosN
Int 21h
Call ConvNUM ; Convierte cantidad 2 a binario
Cmp ErrorCAP, 1 ; ¨Hay error?
Jz CAPCANT02 ; S¡, regresa a capturar la cantidad
Mov CantDosR, Bx ; Guarda conversion de cantidad 2
;------------------------------------------------------------------------------
; DESPUES DE CAPTURAR LAS DOS CANTIDADES SOBRE LAS CUALES SE VA A OPERAR,
; SE DEFINE CUAL ES LA FUNCION POR REALIZAR.
;------------------------------------------------------------------------------
Mov Al, Funcion ; Funcion que selecciono el usuario
Cmp Al, 31h ; Es 1?
Jne FUNCION2 ; No.
Call Incrementa ; Incremento
Jmp OTRA
FUNCION2:
Cmp Al, 32h ; Es 2?
Jne FUNCION3 ; No.
Call Decrementa ; Decrementa
Jmp OTRA
FUNCION3:
Cmp Al, 33h ; Es 3?
Jne FUNCION4 ; No.
Call MuestraAutores ; Muestra Autores
Jmp OTRA
FUNCION4:
;------------------------------------------------------------------------------
; TERMINA EL PROGRAMA
;------------------------------------------------------------------------------
Mov Ax, 4C00h ; Termina el programa sin errores.
Int 21h
;******************************************************************************
; R U T I N A S D E S O P O R T E
;******************************************************************************
;------------------------------------------------------------------------------
; Rutina : Incrementa
;------------------------------------------------------------------------------
Incrementa Proc Near
Mov Ax, CantUnoR ; Primera cantidad (multiplicando)
Call Incremento
;Call convASCII
;Mov Dx, Offset Resulta ; Despliega la cadena del resultado
;Call Imprime
;Mov Dx, Offset ResultaR ; Despliega el resultado.
;Call Imprime
Ret
Incrementa Endp
Incremento proc near
mov ax, 00h
mov dx, 37Ah
out dx, ax
atras: mov dx, 378h ;Indica que puerto se utiliza como salida
mov ax, CantUnoR ;Envía la cantidad uno determinada en el segmento de Not ax ;invierte el dato que enviará al puerto
Not ax
out dx, ax ;Envia el dato al puerto paralelo
cmp CantDosR,0
je salta
mov dx,00h
mov ax,00h
mov ax,CantUnoR
Call ConvASCII
mov Dx, Offset ResultaR
call Imprime
inc CantUnoR ;Incrementa en uno el valor del dato uno
dec CantDosR
Call Retardo ;llama a retardo para poder visualizar el dato
Loop atras ;Itera hasta que llegue al dato maximo
salta:
ret
Incremento endp
Retardo Proc Near
mov Ax,00ffh
atras0: mov Bx,0ffffh
atras1: nop
dec Bx
cmp Bx,0000h
jne atras1
dec Ax
cmp Ax,0000h
jne atras0
ret
Retardo Endp
;------------------------------------------------------------------------------
; Rutina : Decrementa
;------------------------------------------------------------------------------
Decrementa Proc Near
Mov Ax, CantUnoR
Call Decre
;Mov Dx, Offset Resulta ; Despliega la cadena del resultado
;Call Imprime
;Mov Dx, Offset ResultaR ; Despliega el resultado.
;Call Imprime
Ret
Decrementa Endp
Decre proc near
mov ax, 00h
mov dx, 37Ah
out dx, ax
atras3: mov dx, 378h ;Indica que puerto se utiliza como salida
mov ax, CantUnoR ;Envía la cantidad uno determinada en el segmento de Not ax ;invierte el dato que enviará al puerto
Not ax
out dx, ax ;Envia el dato al puerto paralelo
cmp CantDosR,0
je salta2
mov dx,00h
mov ax,00h
mov ax,CantUnoR
Call ConvASCII
mov Dx, Offset ResultaR
call Imprime
dec CantUnoR ;Incrementa en uno el valor del dato uno
dec CantDosR
Call Retardo ;llama a retardo para poder visualizar el dato
Loop atras3 ;Itera hasta que llegue al dato maximo
salta2:
ret
Decre endp
;------------------------------------------------------------------------------
; Rutina :Muestra Autores
;------------------------------------------------------------------------------
MuestraAutores Proc Near
Mov Dx, Offset Autores ; Despliega nombre de autores
Call Imprime
ret
MuestraAutores Endp
;------------------------------------------------------------------------------
; Rutina : Imprime
; Prop¢sito : Despliega una cadena
; Par metros : El registro DX contiene el desplazamiento de la cadena
; Regresa : Nada
;------------------------------------------------------------------------------
Imprime Proc Near
Mov Ah, 9 ; Prepara para desplegar la cadena a traves de la
Int 21h ; INT 21h.
Ret
Imprime Endp
;------------------------------------------------------------------------------
; Rutina : ObtenTecla
; Proposito : Espera a que el usuario digite una tecla
; Parametros : Ninguno
; Regresa : En el registro AL el codigo ASCII de la tecla
;------------------------------------------------------------------------------
ObtenTecla Proc Near
Mov Ah, 0 ; Lee una tecla del teclado a traves de la INT 16h
Int 16h
Ret
ObtenTecla Endp
;------------------------------------------------------------------------------
; Rutina : ConvNUM
; Prop¢sito : Convertir una cadena a un entero largo
; Par metros : La longitud de la cadena y la direccion de la misma, y se
; pasan a la pila.
; Regresa : En el registro BX la cadena convertida en un entero
;------------------------------------------------------------------------------
ConvNUM Proc Near
Mov Dx, 0Ah ; Multiplicador es 10
Cmp Cantidad, 0 ; ¨Es la cantidad 1?
Jnz CONVNUM01 ; NO, asi que es la cantidad 2
Mov Di, Offset CantUnoN + 1 ; Bytes leidos de la cantidad 1
Mov Cx, [Di]
Mov Si, Offset CantUnoN + 2 ; La cantidad 1
Jmp CONVNUM02
CONVNUM01:
Mov Di, Offset CantDosN + 1 ; Bytes leidos de la cantidad 2
Mov Cx, [Di]
Mov Si, Offset CantDosN + 2 ; La cantidad 2
CONVNUM02:
Xor Ch, Ch ; CH = 0
Mov Di, Offset Potencia ; Direccion de la tabla de potencias
Dec Si ; Posiciona Si en el primer byte de la
Add Si, Cx ; cadena capturada y le suma el
Xor Bx, Bx ; desplazamiento de bytes leidos
Std ; para que podamos posicionarnos en el
; final de la misma (apunta al ultimo
; digito capturado). BX = 0 y lee la
; cadena en forma inversa; es decir, de
; atras hacia adelante.
CONVNUM03:
Lodsb ; Levanta un byte del numero (esta instruccion indica
; que el registro AL sera cargado con el contenido
; de la direccion apuntada por DS:SI).
Cmp AL,"0" ; ¨Es menor a 0? (entonces NO es un digito valido)
Jb CONVNUM04 ; S¡, despliega el mensaje de error y termina
Cmp AL,"9" ; ¨Es mayor a 9? (entonces NO es un d¡gito valido)
Ja CONVNUM04 ; S¡, despliega el error y salta
Sub Al, 30h ; Convierte el digito de ASCII a binario
Cbw ; Convierte a palabra
Mov Dx, [Di] ; Obtiene la potencia de 10 que sera usada para
Mul Dx ; multiplicar, multiplica numero y lo suma
;Jc CONVNUM05 ; a BX. Revisa si hubo acarreo, y si lo hubo, esto
Add Bx, Ax ; significa que la cantidad es > 65535.
;Jc CONVNUM05 ; Si hay acarreo la cantidad es > 65535
Add Di, 2 ; Va a la siguiente potencia de 10
Loop CONVNUM03 ; Itera hasta que CX sea = 0
Jmp CONVNUM06
CONVNUM04:
Call HuboERROR ; Algo ocurrio, despliega mensaje y salta
Jmp CONVNUM06
CONVNUM05:
Mov Cantidad, 2 ; Hubo acarreo en la conversion, por lo tanto la
Call HuboERROR ; cantidad capturada es mayor a 65535.
CONVNUM06:
Cld ; Regresa la bandera de direccion a su estado normal
Ret ; y REGRESA.
ConvNum Endp
;------------------------------------------------------------------------------
; Rutina : ConvASCII
; Prop¢sito : Convertir un valor binario en ASCII
; Par metros : El registro par DX:AX
; Regresa : Nada, pero almacena el resultado en el buffer ResultaR
;------------------------------------------------------------------------------
ConvASCII Proc Near
;------------------------------------------------------------------------------
; Lo primero que se hace es inicializar la variable que contendra el
; resultado de la conversion.
;------------------------------------------------------------------------------
Push Dx
Push Ax ; Guarda el resultado
Mov Si, Offset ResultaR ; Inicializa la variable ResultaR llenandola
Mov Cx, 10 ; con asteriscos
Mov Al, '*'
ConvASCII01:
Mov [Si], Al
Inc Si
Loop ConvASCII01
Pop Ax
Pop Dx
Mov Bx, Ax ; Palabra baja de la cantidad
Mov Ax, Dx ; Palabra alta de la cantidad
Mov Si,Offset ResultaR ; Cadena donde se guardara el resultado
Add Si, 11
Mov CX, 10 ; Divisor = 10
OBTENDIGITO:
Dec Si
Xor Dx, Dx ; DX contendra el residuo
Div Cx ; Divide la palabra alta (AX)
Mov Di, Ax ; Guarda cociente (AX)
Mov Ax, Bx ; AX = palabra baja (BX)
Div Cx ; DX tenia un residuo de la division anterior
Mov Bx, Ax ; Guarda el cociente
Mov Ax, Di ; Regresa la palabra alta
Add Dl,30h ; Convierte residuo en ASCII
Mov [Si], Dl ; Lo almacena
Or Ax, Ax ; ¨Palabra alta es 0?
Jnz OBTENDIGITO ; No, sigue procesando
Or Bx, Bx ; ¨Palabra baja es 0?
Jnz OBTENDIGITO ; No, sigue procesando
Ret
ConvASCII Endp
;------------------------------------------------------------------------------
; Rutina : HuboERROR
; Prop¢sito : Desplegar el mensaje de error adecuado.
; Par metros : Nada
; Regresa : Nada
;------------------------------------------------------------------------------
HuboERROR Proc Near
Cmp Cantidad, 0 ; ¨Es la cantidad 1?
Jnz HUBOERROR02 ; No.
Mov Dx, Offset Error1
Call Imprime
Mov ErrorCAP, 1 ; Enciende la bandera de error
Jmp HUBOERROR05
HUBOERROR02:
Cmp Cantidad, 1 ; ¨Es la cantidad 2?
Jnz HUBOERROR03 ; No.
Mov Dx, Offset Error2
Call Imprime
Mov ErrorCAP, 1
Jmp HUBOERROR05
HUBOERROR03:
Cmp Cantidad, 2 ; ¨Cantidad capturada esta fuera de rango ?
Jnz HUBOERROR05 ; No.
Mov Dx, Offset Error3
Call Imprime
Mov ErrorCAP, 1
HUBOERROR05:
Ret
HuboERROR Endp
;------------------------------------------------------------------------------
; Termina programa
;------------------------------------------------------------------------------
End Empieza
Agrego que hay cosillas que no se ocupan pero me dìo flojera quitarlas
![Tongue :P](https://solocodigo.com/Smileys/solocodigo/tongue.gif)
... despues de todo no hando tan mal en esto del ensamblador...
Ademas dicen que se ocupa pa los celulares y no se q otras cosas... entons seguirè en esto... si ago otros programitas os enviarè pa que los vean... jijijijijiji
![Biggrin :D](https://solocodigo.com/Smileys/solocodigo/biggrin.gif)