martes, 19 de marzo de 2019

2. Instrucciones aritmeticas mul


Multi 2: Dos cifras

A continuación una explicación para mejor compresión del funcionamiento del programa.

Código:

.model small ;Modelo de memoria m?s utilizado
.stack
 

.data        ;definición de datos(variables), donde se almacenara información
.code
   chr1  db ? ;primer digito
   chr2  db ? ;segundo digito
   chr3  db ? ;multiplo
   chr4  db ?
   r1    db ? ;resultado 1
   r2    db ? ;resultado 2
   r3    db ?
   r4    db ?
   ac    db 0 ;acarreo
   ac1   db 0
.startup
   ;cls
   mov ah,00h     ;Function(Set video mode)
   mov al,03      ;Mode 80x25 8x8 16
   int 10h        ;Interruption Video

   mov ah,01h     ;Function(character read) Guarda en AL
   int 21h        ;Interruption DOS functions
   sub al,30h     ;ajustamos valores
   mov chr1,al    ;[chr1].chr2 * chr3 = ac.r1.r2

   mov ah,01h     ;Function(character read) Guarda en AL
   int 21h        ;Interruption DOS functions
   sub al,30h     ;Ajustamos valores
   mov chr2,al    ;chr1.[chr2] * chr3 = ac.r1.r2

   mov ah,02h     ;Function(character to send to standard output)
   mov dl,'*'     ;Character to show
   int 21h

   mov ah,01h     ;Function(Read character) Guarda en AL
   int 21h        ;Interruption DOS Functions
   sub al,30h     ;Transform(0dec = 30hex)
   mov chr3,al    ;chr1.chr2 * [chr3] = ac.r1.r2
  
   mov ah,01h     ;Function(Read character) Guarda en AL
   int 21h        ;Interruption DOS Functions
   sub al,30h     ;Transform(0dec = 30hex)
   mov chr4,al    ;chr1.chr2 * [chr3] = ac.r1.r2

   mov ah,02h     ;Character to send to standar output
   mov dl,'='     ;
   int 21h        ;Interruption DOS functions

   ;Realizamos operaci?n   
  
   mov al,chr4  ;unidad del segundo numero
   mov bl,chr2  ;unidad del primer numero
   mul bl       ;multiplicar
   mov ah,0     ;limpiamos ah0
   aam          ;separamos de hex a dec
   mov ac1,ah   ;decenas del primera multiplicacion
   mov r4,al    ;unidades del primera multiplicacion
            
   mov al,chr4  ;unidades del segundo numero
   mov bl,chr1  ;decentas del primer numero
   mul bl       ;multiplicar
   mov r3,al    ;movemos el resultado de la operacion a r3
   mov bl,ac1   ;movemos el acarreo a bl
   add r3,bl    ;sumamos resultado mas acarreo
   mov ah,00h   ;limpiamos ah por residuos
   mov al,r3    ;movemos el resultado de la suma a al
   aam          ;separamos  de hex a dec
   mov r3,al    ;guardamos unidades en r3
   mov ac1,ah   ;guardamos decenas en ac1
  
      

   mov al,chr3    ;al = chr3
   mov bl,chr2    ;bl = chr2
   mul bl         ;AL = chr3*chr2 (BL*AL)
   mov Ah,0h      ;
   AAM            ;ASCII Adjusment
   mov ac,AH      ;ac = AH (Acarreo)
   mov r2,AL      ;r2 = AL       (Unidad del resultado)

   mov al,chr3    ;AL = chr3
   mov bl,chr1    ;BL = chr1
   mul bl         ;AL = chr1*chr3 (BL*AL)
   mov r1,al      ;r1 = AL       (Decena del resultado)
   mov bl,ac      ;BL = Acarreo anterior
   add r1,bl      ;r1 = r1+ac (r1 + Acarreo)
   mov ah,00h     ;
   mov al,r1      ;AL = r1 (Asignaci?n para el ajust)
   AAM            ;ASCII Adjustment
   mov r1,al      ;r1 = AL
   mov ac,ah      ;ac = AH (Acarreo para la Centena del resultado)
  
  
   ;suma final
   ;R4 resulta ser las unidades de mul y no se toma en cuenta ya que se pasa entero
  
  
   mov ax,0000h   ;limpiamos ax
  
   mov al,r3      ;movemos el segundo resultado de la primera mult a al
   mov bl,r2      ;movemos primer resultado de la segunda mult a bl
   add al,bl      ;sumamos
   mov ah,00h     ;limpiamos ah
   aam            ;separamos hex a dec
   mov r3,al      ;r3 guarda las decenas del resultado final
   mov r2,ah      ;r2 se utiliza como nuevo acarreo
  
   mov ax,0000h   ;''''
  
   mov al,ac1     ;movemos el acarreo de la primera mult a al
   mov bl,r1      ;movemos segundo resultado de la segunda mult a bl
   add al,r2      ;sumamos el nuevo  acarreo de la suma anterior  a al
   add al,bl      ;sumamos al a bl
   mov ah,00h     ;limpiamos el registro ah
   aam            ;separamos de hex a dec
   mov r1,al      ;r1 guarda las centenas
   mov r2,ah      ;ah se sigue utilizando como acarreo
  
   mov al,r2      ;movemos el acarreo a al
   mov bl,ac      ;movemos ac a bl
   add al,bl      ;sumamos al a bl
   ;aam            ;separamos hex a dec
   mov ac,al      ;mov al a ac como nuestro acarreo final ;amm ah convierte binario a h

  
 
  
   ;Mostramos resultado
   mov ah,02h 
   mov dl,ac
   add dl,30h
   int 21h        ;Mostramos ac (millar)

   mov ah,02H
   mov dl,r1
   add dl,30h
   int 21h        ;Mostramos r1 (centena)

                 
  
   mov ah,02H
   mov dl,r3
   add dl,30h
   int 21h        ;Mostramos r3 (decena)
  
   mov ah,02H
   mov dl,r4
   add dl,30h
   int 21h        ;unidad
  
.exit
end   


Resultado:




Explicación:




2. Instrucción LOOPZ (Vídeo)

Programa con Loopz


Código:


org 100h
.stack 64
.data
.code
inicio:
mov cx,10 ;cantidad de veces que repetira
mov al,'>' ;caracter inicial

Lee_car:
    mov ah,0eh ;Funcion para imprimir caracter
    int 10h   ;llama a la bios
    
    mov ah,00 ;funcion de espera de un caracter del teclado
    int 16h ;llama al bios
    cmp al,'S' ;compara el caracter con 'S'
    loope Lee_car  ;si es igual salta a otro
    
    mov ah,0eh ;funcion para imprimir caracter
    int 10h ;llamada al bios
    
    ;colocar el fin de la linea para que baje una linea y lo imprima 
    mov ah,0eh ;funcion del bios para imprimir caracter
    mov al,10
    int 10h ;servicio de video
    
    ;colocar el retorno de carro para ir al inicio
    mov al,13
    int 10h ;servicio de video
    ;prepara la salida del programa
    mov ax,4c00h
    int 21h
end inicio



Resultado:


jueves, 14 de marzo de 2019

2. Arreglos

Instrucción CMP, JE, JNE, LOOP


En esta ocasión introducimos un programa que incluye saltos, ciclos, este programa permite comparar una dos palabras y si estas coinciden.


Código:

org 100h          ;directiva

include 'emu8086.inc' 

mov si, 0    ;ponemos si en 0(asigna),el registro 'si' para poder utilizar cmp

comienzo:

mov al, msg2[0]   ;copiar la primera letra de la palabra A al, del
cmp msg[si],"$"   ;si es el fin de la cadena mandar a final,compara msg con msg2
 je final      ; brinca si es igual 
                  ;continuar
cmp msg[si], al   ;comparar si encuentra la primera letra de la cadena en msg2
 jne seguir    ;brinca si es diferente

mov di, 1         ;poner en 1 = di 

comprobar:

 mov al, msg[di]       ;compara en la [?] posicion (di, inc di)msg
 mov bx, di             ;  bx = di
 cmp msg2[si+bx], al     ;posicion de la letra coincidente di(si+bx),comparar con(al) la cadena msg
 jne seguir             ;si no coincide mandar a seguir 
 
 inc di                 ;incrementar di para seguir recorriendo cadena
 cmp msg[di],"$"       ;si es el fin de la cadena y el programa llego

 jz resultado           ;aca quiere decir que la cadena es parte de la palabra


loop comprobar         ;bucle para recorrer cadena

seguir: 
      mov di, 1
 inc si       ;para seguir recorriendo la palabra
loop comienzo   ;bucle principal para recorrer palabra

resultado:

    printn 'multi Coincide con multiplicacion'             
  jmp fin

final:

  print 'No coindice '
fin:

 mov ax, 4c00h 
 ret

msg db "mult$"      ;subcadena a comparar
msg2 db "multiplicacion$" ;cadena
msg5 db "fin$"


Resultado:








miércoles, 13 de marzo de 2019

2. Instrucción LOOP, LOOPNE, JCXZ

Ejemplo con LOOP


Programa 1:


Código: 


org 100h 

include 'emu8086.inc'
mov cx,50 ;cx controla el numero de iteraciones

comienzo:
    printn 'letrero'
    inc cx      ;
LOOP comienzo ;   

ret


Resultado:




Programa 2:

Código: 


org 100h 

include 'emu8086.inc'

.data

msj1 db 10,13, 'letrero $' 
.code 
    mov cx,50 

    comienzo:

    lea dx, msj1
    mov ah, 09
    int 21h
   
    LOOP comienzo ;   

ret


Resultado:


Programa 3:

Código:  

.model tiny
name "bucle"
.data 
msj1 db 10,13,'Letrero $' 
.CODE

 inicio:
 mov cx,50
 comienzo: 
  MOV dx, OFFSET msj1
  MOV ah,09
  int 21h   
     
LOOP comienzo
ret


Resultado:




Programa 4:

Código: 

.model tiny
name "bucle"
.data 
msj1 db 10,13,'Letrero $' 
.CODE

 inicio:
 mov cx,50
 comienzo: 
 
  lea dx, msj1
  MOV ah,09   ;para imprimir
  int 21h   
     
LOOP comienzo
ret


Resultado:





Ejemplo con LOOPNE


Programa 5:

Código: 

.model tiny
name "bucle"
.data 
msj1 db 10,13,'Letrero $' 
.CODE

 inicio:
 mov cx,9
 comienzo: 
 
  lea dx, msj1
  MOV ah,09   ;para imprimir
  int 21h   
     
LOOPNE comienzo
ret ;retorna      
END


Resultado:





Ejemplo con JCXZ

La instrucción JCXZ es un tipo de salto condicional, este solo se hará si en nuestro registro cx tenemos un cero. Solo imprimirá una vez.

Programa 6:

Código: 

.model tiny
name "bucle"
.data 
msj1 db 10,13,'Letrero $' 
.CODE

 inicio:
 mov cx,4 ;0
 comienzo: 
 
  lea dx, msj1
  MOV ah,09   ;para imprimir
  int 21h   
     
JCXZ comienzo
ret ;retorna      
END



Resultado:



domingo, 10 de marzo de 2019

2. Saltos condicionales en Ensamblador (CMP JC JZ JNZ)

Saltos condicionales en Ensamblador (CMP JC JZ JNZ)


Comparar números



Código:


include 'emu8086.inc'
.model small
.stack
.data
    num1 db 8 ;numero a comparar - cambia e intenta
    num2 db 8 ;numero a comparar - cambia e intenta 
    msg1 db 'Numeros iguales','$'
    msg2 db 'Numero 1 mayor','$'
    msg3 db 'Numero 2 mayor','$'
     
.code
    main:
    mov ax, @data
    mov ds,ax
     
    mov al,num1
    cmp al,num2
     
    jc Mayor2   ;Brinca si es mayor el numero 2
    jz igual    ;Salta si es igual
    jnz Mayor1  ;Brinca si es mayor el numero 1
     
.exit
 
igual:
    mov ah,09h
    lea dx ,msg1
    int 21h  
    ;printn 'Los numeros son iguales'
.exit 
 
Mayor1:
    mov ah,09h
    lea dx, msg2
    int 21h
    ;printn 'El numero 1 es mayor'
.exit
 
Mayor2:
    mov ah,09h
    lea dx, msg3
    int 21h
    ;print 'El numero 2 es mayor'
.exit
end

Resultado:






Referencia:
https://www.youtube.com/watch?v=Ng4YEb2Jtcg

2. Saltos Incondicionales (JMP) y Saltos Condicionales

Controlar el flujo del programa es algo muy importante, aquí es donde su programa puede tomar decisiones de acuerdo con ciertas condiciones. 

Salto incondicional (JMP):

La instrucción básica que transfiere el control a otro punto del programa. La sintaxis básica es :

JMP etiqueta


JMP et1 ;Indica a donde saltara et1
.
.
.
et1: ;realiza lo que se encuentra en ella et1
MOV AX, 1 



Programa 1: Salto incondicional

Código:

org    100h

mov    ax, 5          ; se asigna 5 en ax. 
mov    bx, 2          ; se asigna 2 en bx. 

jmp    calc            ; va a 'calc'. 

back:  jmp stop      ; va a 'stop'. 

calc:
add    ax, bx         ; suma bx y ax. 
jmp    back           ; va a la etiqueta 'back'. 

stop:

ret                   ; return to operating system. 


Resultado:






Salto condicional (CMP):


Hay instrucciones que realizan saltos condicionales (salta solo cuando alguna condiciones están en acción)


Programa 2: Salto condicional, Compara un número

Código: 

include "emu8086.inc"

org    100h

mov    al, 25     ; establece al a 25. modificar a 10 para probar el igual
mov    bl, 10     ; establece bl a 10. 

cmp    al, bl     ; compara al - bl. 
je     equal      ; salta si al = bl (zf = 1). 

putc   'n'        ; si llega aqui, entonces al <> bl,
print  'No es igual'  

jmp    stop       ;  imprime 'n', y salta a stop. 

equal:            ; si llega aqui, 
putc   'y'        ; entonces al = bl, imprime 'y'. 
print  'Es igual'   
stop: ret ; llega aqui no importa que.


Resultado:

Se asigna valores a los registros, compara  "al" y "bl".



Al ser diferente imprime n "No es igual".


En caso de comparar valores iguales imprime lo siguiente:




Instrucción LOOP:

Programa 3: LOOP Imprime 5 veces 1233333233333233333233333233333, se usa push para decrementar

Código:


org 100h

mov bx, 0  ; contador de pasos total. 

mov cx, 5
k1: 
   ;add bx, 1
    mov al,' ' ;guardamos un espacio en al 
    mov ah, 0eh
    int 10h 
    mov al, '1' ; al=1
    mov ah, 0eh ;invoca el servicio de impresion video
    int 10h     ;imprimimos
    push cx     ;resta 1 a cx: cx=cx-1 para loop1
    mov cx, 5   ;cx a 5 para loop 2
      k2: 
      ;add bx, 1
      mov al, '2'  ;al=2
      mov ah, 0eh  ;impresion de video    
      int 10h      ;imprime
      push cx        ;decrementa -1 loop2
         mov cx, 5    ;cx=5 loop3
         k3: add bx, 1  ;
         mov al, '3'    ;al=3
         mov ah, 0eh    ;impresion video
         int 10h        ;imprimimos
         loop k3    ; internal in internal loop. 
      pop  cx       ;resta 1 a cx loop3
      loop  k2      ; internal loop. bucle interno
    pop cx          ;resta 1 a cx loop2
loop k1             ; external loop. bucle externo

ret   ;retornamos control al ordenador


Resultado:




Instrucciones de salto que prueban una sola bandera.




Saltar instrucciones para números firmados.



 Saltar instrucciones para números sin firmar.


Bucle




Referencia:

https://www.youtube.com/watch?v=Ng4YEb2Jtcg
http://jbwyatt.com/253/emu/asm_tutorial_07.html
https://www.youtube.com/watch?v=llCG44dzPQM

jueves, 7 de marzo de 2019

2. Comparaciones, saltos, ciclos condicionales, incrementos y decrementos

Sentencias condicionales 



Control de Bucles (instrucciones simples)



Éstas posibilitan el grupo de control más elemental de nuestros programas. Un bucle es
un bloque de código que se ejecuta varias veces. Hay 4 tipos de bucles básicos:

  • Bucles sin fin
  • Bucles por conteo
  • Bucles hasta
  • Bucles mientras


Las instrucciones de control de bucles son las siguientes:




La instrucción LOOP va acompañada de el registro CX como contador, que es para la iteración.

Instrucciones de prueba, Comparación y Saltos.


CMP y TEST son como el if compara y verifica.



Referencia:
http://moisesrbb.tripod.com/unidad5.htm#u511
https://drive.google.com/file/d/1GEXHus3zVUPLlDw4ASeUjRXcp53D_c31/view
http://jbwyatt.com/253/emu/asm_tutorial_07.html

martes, 5 de marzo de 2019

1.8 DESPLEGADO DE MENSAJES EN EL MONITOR


Int 21H
Esta interrupción tiene varias funciones, para acceder a cada una de ellas es necesario que el el registro AH se encuentre el número de función que se requiera al momento de llamar a la interrupción.

Funciones para desplegar información

02H Exhibe salida
Uso: Despliega un carácter a la pantalla.
Registros de llamada:
AH = 02H
DL = Valor del caracter a desplegar.

09H Impresión de cadena

Uso: Despliega una cadena de caracteres en la pantalla.
Registros de llamada:
AH = 09H
DS:DX = Dirección de inicio de una cadena de caracteres


Esto se puede hacer de 2 maneras, utilizando offset o con el nemónico lea.
offset va a conseguir cada dirección de memoria de cada carácter y lo devolverá a la 
instrucción solicitada.


Con lea esta solicitud de direcciones por cada carácter se hace de forma automática.

Libreria emu8086.inc



1.7 COMPILADORES, PROCESO DE ENSAMBLADO Y LIGADO


Imagen relacionada

El lenguaje ensamblador, es un lenguaje de programación que es una traducción directa del código máquina(este código es interpretado por el microprocesador), para que pueda ser entendible, por lo tanto es un lenguaje nivel.

Consta de 3 partes:
Sección de pila
Sección de datos o variables.
Seccion de codigo.

Proceso de Ensamblado y ligado

Ensamblado y ligado Para poder crear un programa se requieren varias herramientas: Primero un editor para crear el programa fuente. Segundo un compilador que no es más que un programa que “traduce” el programa fuente a un programa objeto. Y tercero un enlazador o linker , que genere el programa ejecutable a partir del programa objeto.

El programa utiliza un editor de texto para crear un archivo de texto ASCII, conocido como archivo de código fuente, este con una extensión asm, haciendo uso de un editor cualquiera(notepad++).

El ensamblador lee el archivo de código fuente y produce un archivo de código objeto, una traducción del programa a lenguaje máquina.
De manera opcional, produce un archivo listado. Si ocurre un error, el programador debe regresar al paso anterior y corregir el programa. Durante el ensamble también puede generarse un archivo de referencias cruzadas, que es útil cuando se manejan programas en varios archivos.

El enlazador lee el archivo de código objeto y verifica si el programa contiene alguna llamada a los procedimientos en una biblioteca de enlace. El enlazador copia cualquier procedimiento requerido de la biblioteca enlace, lo combina con el archivo de código objeto y produce el archivo ejecutable. De manera opcional, el enlazador puede producir un archivo de mapa.
El archivo de mapeo, indica donde se localiza cada segmento o sección del programa en el archivo ejecutable y que es útil sobre todo para programas divididos.
La herramienta cargador (loader) del sistema operativo lee el archivo ejecutable y lo carga en memoria, y bifurca la CPU hacia la dirección inicial del programa, para que este empiece a ejecutarse

La principal diferencia entre compilador y ensamblador llega en el hecho de que generalmente los compiladores traducen un código a un lenguaje intermedio, como puede ser ensamblador, una vez que se hizo esto, se apoyan de esa traducción para transformar el código a lenguaje máquina.
Por el contrario el ensamblador, lee tu código, te detecta errores, y si no tenemos errores traduce directamente a lenguaje máquina, es decir, hace una traducción directa.

Ambos utilizan lo que se conoce como ligadores o enlazadores, estos al traducir un formato ejecutable, generalmente se topan con segmentos de código como las importaciones o llamadas a otros programas, es aquí donde ellos se encargan de enlazar los códigos y archivos faltantes para una correcta traducción a Lenguaje Máquina.


viernes, 1 de marzo de 2019

1. Uso de librería emu8086 (parte 3)


Programa 1: Demostración de códigos.

Código:

include "emu8086.inc"
org 100h
 .data 
  mensaje1 db 13,10,"print_string imprime un mensaje guardado en el registro SI",0
.code
  print "Print muestra un mensaje en pantalla"    
  lea si,mensaje1
  call print_string
  gotoxy 6,6 ;esto mueve el cursor a la posicion deseada 
  print "GOTOXY mueve el cursor a la posicion deseada"
  gotoxy 6,7
  print "scan_num solicita un valor por teclado, este se guarda en cl: "
  call scan_num  
  xor ax,ax
  mov al,cl
  gotoxy 6,8
  print "print_num imprime en pantalla el valor numerico de al: "
  call print_num 
  gotoxy 6,9
  print "Putc imprime un solo caracter: "
  putc "a"  
  
  
  define_print_num 
  define_scan_num      
  define_print_num_uns
  define_print_string  
end


*

Programa 2: Hello World

Código:

include emu8086.inc

ORG    100h

PRINT 'Hello World!'

GOTOXY 10, 5

PUTC 65           ; 65 - is an ASCII code for 'A'
PUTC 'B'

RET               ; return to operating system.
END               ; directive to stop the compiler.


Resultado:




Programa 3: Demostracion del uso print_string y get_string

Código:


; demonstrate get_string and print_string
;----------------------------------------
include 'emu8086.inc'
ORG    100h

LEA    SI, msg1       ; set up pointer (SI) to msg
                      ; to ask for the number
CALL   print_string   ; print message that SI points to

LEA    DI, buffer     ; set up pointer (DI) to input buffer
MOV    DX, bufSize    ; set size of buffer
CALL   get_string     ; get name & put in buffer

LEA    SI, newln      ; point at CR/LF / Hello message 
CALL   print_string   ; print message that SI points to

RET                   ; return to operating system.

; data
msg1   DB "Enter your name: ", 0  
newln  DB 13, 10
       DB "Hello, "
buffer DB 20 DUP (0)  ; input buffer for get_string   
bufSize = $-buffer    ; calculates size of buffer

DEFINE_GET_STRING
DEFINE_PRINT_STRING
END                   ; directive to stop the compiler.




Resultado:






Programa 4: Uso scan_num, print_num, pthis




Código:




; demonstrate scan_num, print_num, pthis
;----------------------------------------
include 'emu8086.inc'
ORG    100h

LEA    SI, msg1       ; ask for the number
CALL   print_string   ;
CALL   scan_num       ; get number in CX.

MOV    AX, CX         ; copy the number to AX.

; print the following string:
CALL   pthis
DB  13, 10, 'You have entered: ', 0

CALL   print_num      ; print number in AX.

RET                   ; return to operating system.

; data
msg1   DB  'Enter the number: ', 0

; macros to define procs
DEFINE_SCAN_NUM
DEFINE_PRINT_STRING
DEFINE_PRINT_NUM
DEFINE_PRINT_NUM_UNS  ; required for print_num.
DEFINE_PTHIS

END                   ; directive to stop the compiler.


Resultado:




Programa 5: hola mundo uso de gotoxy

Código:

name 'hola mundo'

include 'emu8086.inc'


org 100h

.code
gotoxy 5,5

printn "hola mundo"
gotoxy 5,6

printn "hola mundo 2"
gotoxy 5,7

print "dame un numero:"

call scan_num

define_scan_num

putc "A"

ret


Resultado:




Programa 6: hola mundo  gotoxy- imprime número

Código:
 

include 'emu8086.inc'

org 100h

.code    
Cursoroff      ;apaga el cursor
call scan_num  ;pide un numero

define_scan_num  ;define la funcion 
gotoxy 2,5 
putc 'A'   ;imprime un solo caracter
gotoxy 5,7    ;define en donde se ira a la pantalla
print 'dame un numero: '
call scan_num   
mov ax,cx 
gotoxy 5,8 
call print_num                   
   
define_print_num 
define_print_num_uns
end
ret


Resultado:







Referencia:
http://jbwyatt.com/253/emu/asm_tutorial_05.html


3. Colores Modificado 9

Modificación del programa # 9 " Colores " Por mi compañero Ambrocio isaias Laureano CR EQU 13 ;Declaro retorno de carro LF...