Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Inicio:
Opcion:
Opt2:
Opt3:
Opt4:
Fin:
mov ax, 04C00H ; salir
int 21H ; fin de programa
;
==================================================================
====
; funcion DoDiv
; ingresa datos y opera la division
DoDiv:
call NewLine ;
Call NewLine ;
Call NewLine ;
Call NewLine ;
call Write ;
mov si, prd ; resultado de la division en binario
mov cx, 20 ;
mov bx, Res ;
Call NewLine ;
Call NewLine ;
ret ;
DoDivFin:
ret ;
;
==================================================================
====
; funcion DoMulti
; ingresa datos y opera la multiplicacion
DoMulti:
call NewLine ;
Call NewLine ;
Call NewLine ;
Call NewLine ;
call Write ;
mov si,Res ;
Call NewLine ;
Call NewLine ;
ret ;
;
==================================================================
====
; funcion DoResta
; ingresa datos y opera
DoResta:
call NewLine ;
Call NewLine ;
mov cx, 20 ;
mov di, OpA ;
call Read128BitNum ;
Call NewLine ;
mov dx, Msg7 ;
call Write ;
mov cx, 20 ;
mov di, OpB ;
call Read128BitNum ;
Call NewLine ;
call Resta128Bits ;
call Write ;
call Write128BitS ;
mov si,Res ;
call WriteNum ;
Call NewLine ;
Call NewLine ;
ret ;
;
==================================================================
====
; funcion DoSuma
; ingresa datos y opera
DoSuma:
call NewLine ;
Call NewLine ;
mov cx, 20 ;
mov di, OpA ;
call Read128BitNum ;
Call NewLine ;
mov cx, 20 ;
mov di, OpB ;
call Read128BitNum ;
Call NewLine ;
call Suma128Bits ;
call Write ;
call Write128BitS ;
mov si,Res ;
call WriteNum ;
Call NewLine ;
Call NewLine ;
ret ;
;
==================================================================
====
; funcion CeroStr
; llena una cadena de 0's
; Parametro cx cantidad de digitos
; Parametro di direccion de la cadena a rellenar
CeroStr:
cld ;
CeroStrCopiar:
movsb ;
dec si ;
loop CeroStrCopiar ;
ret ;
;
==================================================================
====
; funcion Reset
; pone a 0 las variables A B y RES, TMP y PRD
Reset:
ret ;
;
==================================================================
====
; funcion Menu
; imprime las cadenas que forman el menu
Menu:
call NewLine ;
call NewLine ;
call NewLine ;
call NewLine ;
ret ;
;
==================================================================
====
; funcion Cmp128Bits
; compararacion de 128 bits
; si operador a
; di operador b
; al = 0 -> A = B
; al = 1 -> A > B
; al = 2 -> A < B
Cmp128Bits
ja Cmp128BitsAgB ;
jb Cmp128BitsBgA ;
ja Cmp128BitsAgB ;
jb Cmp128BitsBgA ;
ja Cmp128BitsAgB ;
jb Cmp128BitsBgA ;
mov eax, [si] ;
mov ebx, [di] ;
ja Cmp128BitsAgB ;
jb Cmp128BitsBgA ;
mov al, 0 ;
cmp al , 0 ;
ret ;
Cmp128BitsAgB :
mov al, 1 ;
cmp al, 0 ;
ret ;
Cmp128BitsBgA :
mov al, 0 ;
cmp al, 1 ;
ret ;
;
==================================================================
====
; funcion SetCero128Bits
; si numero
; pone un numero de 128bits a cero
SetCero128Bits:
;
==================================================================
====
; funcion Inc128Bits
; si operador a
; ecx, incremento
; incrementa el numero en SI , CX veces
; osea, OP = OP + CX , pasando la direccion
; de OP en si
Inc128Bits:
ret ;
;
==================================================================
====
; funcion Div128Bits
; si operador a
; di operador b
; bx resultado
; divide dos numeros mediante
; restas sucesivas, y optimizada con dezplamientos
; A / B ==>
; SI A > ( B * 4096 ) ENTONCES
; A = A - 4096
; RES = RES + B * 4096
; para optimizar divisiones grandes
Div128Bits:
push si ;
push di ;
push bx ;
mov si, di ;
mov di, tmp ;
Div128BitsL1:
pop bx ;
pop di ;
pop si ;
push si ;
push di ;
push bx ;
pop bx ;
pop di ;
pop si ;
push si ;
push di ;
push bx ;
push si ;
push di ;
push bx ;
mov bx, si ;
pop bx ;
pop di ;
pop si ;
push si ;
push di ;
push bx ;
mov si, bx ;
pop bx ;
pop di ;
pop si ;
Div128BitsN:
push si ;
push di ;
push bx ;
mov bx, si ;
pop bx ;
pop di ;
pop si ;
push si ;
push di ;
push bx ;
mov ecx, 1 ; incrementar el resultado en 1
mov si, bx ;
call Inc128Bits ;
pop bx ;
pop di ;
pop si ;
jmp Div128BitsCiclo ;
Div128BitsFin:
ret ;
;
==================================================================
====
; funcion ShiftLeft128Bits
; si numero a ser desplazado
; di resultado
; desplazar a la izquierda un numero de 128bits
ShiftLeft128Bits:
ret ;
;
==================================================================
====
; funcion Mult128Bits
; di operador a
; si operador b
; resultado en bx
; multiplicar con sumas repetidas en un ciclo
; y optimizaciones mediante shift a la izquierda
Mult128Bits:
Mult128BitsCiclo:
jz NEAR Mult128BitsFin ;
jz NEAR Opt23 ;
push di ;
push si ;
mov si, di ;
mov di, tmp ;
call ShiftLeft128Bits ;
mov si, tmp ;
mov cx, 30 ;
Mult128BitsL1:
call ShiftLeft128Bits ;
loop Mult128BitsL1 ;
mov si, bx ;
call Suma128Bits ;
pop si ;
pop di ;
push bx ;
push si ;
push di ;
mov bx, si ;
call Resta128Bits ;
pop si ;
pop di ;
pop bx ;
jmp Mult128BitsCiclo ;
Opt23:
jz NEAR Opt7 ;
push di ;
push si ;
mov ecx, 5 ;
mov si, di ;
mov di, tmp ;
call ShiftLeft128Bits ;
mov si, tmp ;
mov cx, 22 ;
Mult128BitsL2:
call ShiftLeft128Bits ;
loop Mult128BitsL2 ;
mov si, bx ;
call Suma128Bits ;
pop si ;
pop di ;
mov ecx, 8388608 ;
call Dec128Bits ;
jmp Mult128BitsCiclo ;
Opt7:
jb Mult128BitsN ;
push di ;
push si ;
mov si, di ;
mov di, tmp ;
call ShiftLeft128Bits ;
mov si, tmp ;
mov cx, 6 ;
Mult128BitsL3:
call ShiftLeft128Bits ;
loop Mult128BitsL3 ;
mov si, bx ;
call Suma128Bits ;
pop si ;
pop di ;
call Dec128Bits ;
jmp Mult128BitsCiclo ;
Mult128BitsN:
push si ;
mov si, bx ;
call Suma128Bits ;
pop si ;
mov ecx, 1 ;
call Dec128Bits ;
jmp Mult128BitsCiclo ;
Mult128BitsFin:
ret ;
;
==================================================================
====
; Dec128Bits
; decrementar un numero en ECX
; si el numero
; si = si - ecx
; resta de 32 bits el segundo operador
Dec128Bits ;
mov edx, 0 ;
ret ;
;
==================================================================
====
; funcion Resta128Bits
; si operador a
; di operador b
; resultado en bx
; resta de dos numeros de 128bits en binario
Resta128Bits:
ret ;
;
==================================================================
====
; funcion Suma128Bits
; di operador a
; si operador b
; resultado en bx
; sumar dos numeros de 128 bits
Suma128Bits:
ret ;
;
==================================================================
====
; funcion Write128BitS
; bx cadena
; si numero
; convierte un numero de binario a decimal y lo almacena en una cadena
; como texto
; soporta numeros negativos en formato de complemento a dos.
; si es negativo llama a una funcion Write128BitNum que antepone un
; signo negativo y calcula el complemento osea 0 - Numero antes de
; convertirlo a decimal
Write128BitS:
jz Write128BitPos ;
call Write128BitNumNeg ;
jmp Write128BitSFin ;
Write128BitPos:
call Write128BitNum ;
Write128BitSFin:
ret ;
;
==================================================================
====
; funcion Write128BitNumNeg
; sacar numero negativo.
; bx cadena de salida
; si numero de entrada
; convertir un numero negativo en base binaria
; a un numero decimal con signo "-" antepuesto
Write128BitNumNeg:
add bx, cx ;
push si ;
push bx ;
mov bx, si ;
mov di, si ;
call Resta128Bits ;
pop bx ;
pop si ;
Write128BitNumcicloNeg:
push bx ;
call DivDiez ;
pop bx ;
or al, 0x30 ;
mov [bx],al ;
dec bx ;
; call PutCh ;
jnz Write128BitNumcicloNeg
ret ;
;
==================================================================
====
; funcion Write128BitNum
; BinToDec en cadena
; si numero para convertir
; bx cadena para rellenar
; cx tamaño de la cadena
; convierte un numero positivo en binario a decimal
Write128BitNum:
mov di, si ;
add bx, cx ;
Write128BitNumciclo:
push bx ;
call DivDiez ;
pop bx ;
or al, 0x30 ;
mov [bx],al ;
dec bx ;
; call PutCh ;
jnz Write128BitNumciclo ;
ret ;
;
==================================================================
====
; funcion DivDiez
; Divide un numero de 128 bits, por 10
; USADA SOLO PARA CONVERTIR DE BINARIO A DECIMAL,
; Parametro si direccion de la 128 bits de entrada
; parametro di direccion de los 128 bits de salida
; NOTA: esta funcion usa DIV solo para dividir por diez
; y obtener el residuo que es utilizado en la conversion
; de binario a decimal, no participa en la division.
DivDiez:
xor edx,edx ;
mov eax, [si + 12] ;
mov ebx, 10 ;
div ebx ;
ret ;
;
==================================================================
====
; funcion Read128BitNum
; USAL MUL SOLO PARA CONVERTIR DE DECIMAL A BINARIO
; AL PRESIONAR UN DIGITO, MULTIPLICA POR 10 y SUMA
; EL DIGITO
; lee un numero de 128 bits
; Parametro di direccion de la 128 bits de salida
; cx , cantidad de digitos
Read128BitNum:
Read128NumCiclo:
call GetCh ;
cmp al, 13 ;
je NEAR Read128NumFin ;
cmp cx, 0 ;
je NEAR Read128NumFin ;
dec cx ;
push cx ;
push ax ;
or al, 0x30 ;
call PutCh ;
mov eax, 10 ;
mov ebx, [di] ;
mul ebx ;
mov [di], eax ;
mov ecx, edx ;
mov eax, 10 ;
mov ebx, [di + 4] ;
mul ebx ;
add eax, ecx ;
mov [di + 4], eax ;
adc edx, 0 ;
mov ecx, edx ;
mov eax, 10 ;
mov ebx, [di + 8] ;
mul ebx ;
add eax, ecx ;
mov [di + 8], eax ;
adc edx, 0 ;
mov ecx, edx ;
mov eax, 10 ;
mov ebx, [di + 12] ;
mul ebx ;
add eax, ecx ;
mov [di + 12], eax ;
pop ax ;
and eax, 0xF ;
mov ebx, [di] ;
add eax, ebx ;
mov [di], eax ;
mov eax, [di+4] ;
adc eax, 0 ;
mov [di+4], eax ;
mov eax, [di+8] ;
adc eax, 0 ;
mov [di+8], eax ;
mov eax, [di+12] ;
adc eax, 0 ;
mov [di+12], eax ;
pop cx ;
jmp Read128NumCiclo ;
Read128NumFin:
call NewLine ;
ret ;
;
==================================================================
====
; funcion WriteNum
; Imprime un numero sin ceros a la izquierda
; Parametro si direccion de la cadena a imprimir
; imprime un numero almacenado en una cadena
; quitando los ceros a la izquierda
; 0000000000035 -> 35
WriteNum:
WriteNumCiclo:
jne WriteNumFin ;
inc si ;
loop WriteNumCiclo ;
WriteNumFin:
mov dx, si ;
call Write ;
ret ;
;
==================================================================
====
; funcion Write
; imprimir una cadena en pantalla
;
; Parametro dx direccion de la cadena
; imprime una cadena terminada en $ en pantalla
Write:
push ax ; preservar ax
mov ah,0x9 ; funcion 9, imprimir en pantalla
int 0x21 ; interrupcion dos
pop ax ; restaurar ax
ret ; return
;
==================================================================
====
; funcion Writeln
; imprimir + enter
;
; Parametro dx direccion de la cadena
Writeln:
;
==================================================================
====
; funcion HasKey
; hay una tecla presionada en espera?
; zf = 0 => Hay tecla esperando
; zf = 1 => No hay tecla en espera
; como el ReadKey de pascal: NO UTILIZADA
HasKey:
push ax ;
pop ax ;
ret ; return
;
==================================================================
====
; funcion ClearIn
; Borrar Buffer del Teclado
; NO UTILIZADA, me hiba a servir para limpiar posibles
; pulsaciones dobles en el menu, pero no se dio el
; problema al probar con la funcion GETCH
ClearIn
ClearInL1:
call HasKey ;
jz ClearInL2 ;
call GetCh ;
jmp ClearInL1 ;
ClearInL2: ;
ret ;
;
==================================================================
====
; funcion PutCh
; imprimir el caracter ascii en al, en pantalla
; Parametro al el caracter a imprimir
PutCh:
ret ;
;
==================================================================
====
; funcion NewLine
; nueva linea
; imprimir enter en pantalla
NewLine:
;
==================================================================
====
; funcion GetCh
; ascii tecla presionada
; Salida en al codigo ascii sin eco, via BIOS
GetCh:
xor ah,ah ;
int 0x16 ;
ret ;
;
==================================================================
====
;==============================|
; DATA |
;==============================|
Cero128Bits DW
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
DosA31 DW
0x0000,0x8000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
OpA DW 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
OpB DW 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
prd DW 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
tmp DW 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
Buff DB "000000000000000000000000000000$"
Res DB "000000000000000000000$"
OperA DB "0000000000000000000000000$"
CRLF DB 0DH,0AH,'$'
strCero DB '0'
;==============================|
; STACK |
;==============================|
Lo que haremos siempre que vayamos a general el .exe de algún código .asm sera lo
siguiente:
- INICIO > EJECUTAR > CMD (se nos abrira la consola msdos)
cd..
cd..
cd tasm
cd bin
- Ahora que estamos en el directorio donde tenemos nuestro codigo, (el arqui.asm)
pasaremos a crear el .obj y linkarlo. Para ello usaremos los comandos:
tasm arqui
tlink arqui
Sin cerrar la ventana del dos, escriban arqui y se ejecutara el programa. Les mostrara
por pantalla el menú de las operaciones a realizarse.