martes, 29 de enero de 2019

UNIDAD l



LENGUAJE ENSAMBLADOR

El lenguaje ensamblador, o assembler (en inglés assembly language y la abreviación asm), es un lenguaje de programación de bajo nivel. Consiste en un conjunto de mnemónicos que representan instrucciones básicas para los computadores, microprocesadores, microcontroladores y otros circuitos integrados programables. Implementa una representación simbólica de los códigos de máquina binarios y otras constantes necesarias para programar una arquitectura de procesador y constituye la representación más directa del código máquina específico para cada arquitectura legible por un programador. Cada arquitectura de procesador tiene su propio lenguaje ensamblador que usualmente es definida por el fabricante de hardware, y está basada en los mnemónicos que simbolizan los pasos de procesamiento (las instrucciones), los registros del procesador, las posiciones de memoria y otras características del lenguaje. Un lenguaje ensamblador es por lo tanto específico de cierta arquitectura de computador física (o virtual). Esto está en contraste con la mayoría de los lenguajes de programación de alto nivel, que idealmente son portables.

TIPOS DE LENGUAJE ENSAMBLADOR

ENSAMBLADORES CRUZADOS: permiten el soporte de medios físicos como pantallas, impresoras, teclado, etc. y la programación que ofrecen maquinas potentes que luego serán ejecutados en sistemas especializados.

ENSAMBLADORES RESIDENTES: permanecen en la memoria de la computadora, y cargan para su ejecución al programa objeto producido. es el indicado para el desarrollo de pequeños sistemas de control.

MACRO ENSAMBLADORES: permiten el uso de macro instrucciones, son programas grandes que no permanecen en memoria una ves que se a generado el código objeto, normalmente son programas complejos y residentes.

MICRO ENSAMBLADORES: Indica al interprete las instrucciones de como debe actuar la CPU. 

ENSAMBLADORES DE UNA FASE: leen una linea de programa fuente y la traducen directamente para producir una instrucción en lenguaje maquina, estos ensambladores son sencillos, baratos y ocupan poco espacio.


ENSAMBLADORES DE DOS FASES: se llaman así por que realizan la traducción en dos etapas, en la primera fase revisan el código fuente y lo construyen en una tabla de símbolos, en la segunda fase vuelven a leer el programa fuente y pueden traducirlo por completo. estos ensambladores son los mas utilizados en la actualidad.


PROGRAMA Hola Mundo EN LENGUAJE ENSAMBLADOR

Programa: Emu8086


Código:
.MODEL SMALL
.STACK
.DATA
CADENA1 DB 'HOLAMUNDO $'
CADENA2 DB 'HOLAMUNDO2 $'
.CODE
PROGRAMA:
    MOV AX,@DATA
    MOV DS,AX
    MOV DX,OFFSET CADENA1
    MOV AH,9
    INT 21H 
    MOV DX,OFFSET CADENA2
    MOV AH,9
    INT 21H 
END PROGRAMA

Ejecución:




PROGRAMA Hola Mundo, HECHO DE DIFERENTE FORMA:

Ejemplo 1


CODE SEGMENT
ASSUME CS:CODE, DS:CODE, SS:CODE, ES:CODE
ORG 100H
principio:
mov ah, 0Fh
mov ah, 0
int 10h
lea dx, mensaje_a_mostrar
mov ah, 9h
int 21h
int 20h
mensaje_a_mostrar db "Hola Mundo!$",0

CODE ENDS
end principio


Ejecución:



Ejemplo 2

CODE SEGMENT
ASSUME CS:CODE, DS:CODE, SS:CODE, ES:CODE
ORG 100H
principio:
mov ah,0
int 16h
mov ah, 0Fh
mov ah, 0
int 10h
lea dx, mensaje_a_mostrar
mov ah, 9h
int 21h
int 20h
mensaje_a_mostrar db "Hola Mundo!$",0
CODE ENDS
end principio

Ejecución:


LISTA DE INTERRUPCIONES DE LENGUAJE ENSAMBLADOR (8086)
https://drive.google.com/file/d/12l2J-aq5wKjOaAtSOdDQwHwN_ytdhjC8/view
PROGRAMA EN ENSAMBLADOR 8086: OPERACIONES DE suma, resta e incremento
Programa #1
org 100h
;suma numeros de un solo digito

mov ax, 8H  ;asigna un valor a ax
mov bx, 4H  ;asigna un valor a bx
add ax,bx   ;suma los valores ax y bx,guarda en ax
mov bx,5    ;cambia valor de bx
sub ax,bx   ;resta ax y bx
mov bx,3    ;cambia valor de bx a 3
inc bx      ;incrementa bx a 4

mov ax,6    ;cambia el valor de ax a 6

hlt  ; termina el proceso
USO DE REGISTROS EN ENSAMBLADOR 8086


En esta ocasión veremos los registros básicos a la hora de programar dentro de ensamblador. Si bien, tenemos varios registros dentro de lo que es nuestro ensamblador, pero en esta oportunidad solo nos enfocaremos en los mas básicos y en los cuales estaremos trabajando durante el curso.

Los registros que veremos son:
AX    Acumulador
BX    Registro base
CX    Registro contador
DX    Registro de datos

El registro AX se usa para almacenar resultados, lectura o escritura desde o hacia los puertos.
El registro BX sirve como apuntador base o indice.
El registro CX se utiliza en operaciones de iteracion, como un contador que se va incrementado o decrementa de acuerdo con el tipo de instrucción dada. Mas comúnmente, utilizado en algún ciclo.
El registro DX se usa como puente para el acceso de datos.

Cada uno de estos registros sirven de diferente forma dentro de los programas. Anteriormente, habíamos utilizado el registro AX y BX para guardar datos numéricos en hexadecimal.

A continuación anexare un programa en el cual, estamos imprimiendo el abecedario utilizando algunos de los registros que ya hemos mencionado:


CÓDIGO:
;uso del registro cx
org 100h
    MOV DL, "A" ;se transfiere la letra A al registro (valor en hexadecimal del assembler 8086"dar clic al codigo ascii")
    MOV CX, 26 ;se asigna el 26 al registro cx
  imprime: ;va a imprimir hasta acabar las 26
    MOV AH, 02 ;se va a tranferir el 02 al acumulador de byte
    INT 21h ;dato ascii leido desde el teclado
    INC DL  ;incrementa dl
LOOP imprime ;continua


lo que estamos haciendo aquí es mandar el valor de cada una de las letras a nuestros registros, enviamos un numero definido de letras que va a imprimir, en nuestro caso las 26 letras del abecedario.
Al enviar las letras, la maquina no las manda como si fuera una A en si, lo que envía a los registros es el codigo ascii que reconoce el ensamblador para saber que es el carácter "A"




IMPRESIÓN DE CARACTERES EN PANTALLA Y LECTURA DESDE EL TECLADO.
Anteriormente habíamos dicho que al enviar un carácter a lenguaje ensamblado en nuestros registros, este no lo toma como letra en si. Sino, que toma el código ascii de esta letra. (ya habíamos visto esa tabla)






Si bien, al mandar un numero como caracter ("2") usando el servicio 01 de la interrupcion 21h para ingresar tu valor por teclado, siempre guardara el equivalente en codigo ascii del numero en la parte alta del registro ax.
Nota: este tipo de servicios solo va a leer una sola letra o caracter.
Cuando se necesitan utilizar el valor numérico real, se debe realizar una operación sobre ese registro para poder deducir el valor real de ese codigo ascii guardado en la parte baja del registro AX
Ya sea realizar una resta de 48 o 30h (esto debido al codigo ascii de los numeros, donde el 0 es 48,etc).
Al momento de imprimir el resultado de dicha operacion(suma,resta,division etc) se debe regresar al valor de codigo ascii equivalente al resultado, por lo que se debe volver a sumar ya sea 48 o 30h.
Posteriormente para lanzar en pantalla dicho dato, usamos el servicio 02 de la interrupción 21h para imprimir lo deseado en nuestra pantalla de comandos y mover el valor que deseamos imprimir a la parte baja del registro DX.
A continuación dejo dos sintaxis de programas que demuestran lo siguiente:


PROGRAMA 1: MUESTRA UN DETERMINADO MENSAJE EN UNA CIERTA CANTIDAD DE VECES QUE EL USUARIO ELIJA.

CÓDIGO:
.model small
.stack 64
.data
mensaje db "Ingrese el numero de veces que se repetira el mensaje (1-9)",13,10,'$'
repetir db 13,10,"Repitiendo el ciclo $"
.code
inicio proc far
     
    mov ax,@data
    mov ds,ax
     
    mov ah,09
    lea dx,mensaje
    int 21h
     
    mov ah,01
    int 21h
    ;convierte a valor lo que se teclea
    sub al,30h   
    mov cl,al
     
    ciclo:
     mov ah,09
     lea dx,repetir
     int 21h
    loop ciclo
    ;se cierra el programa con esas lineas
    mov ax,4c00h
  inicio endp
end


PROGRAMA 2: SUMA DE DOS NÚMEROS DADOS POR EL  USUARIO Y MENSAJE DEL RESULTADO DE DICHA SUMA.

Este programa lo puedes encontrar en la siguiente liga, que en si esta entrada es un resumen de este video. Vídeo sobre servicios de interrupción 21h


CÓDIGO:

.model small
.stack 64
.data
    n1 db 0
    n2 db 0
    suma db 0
    msg1 db "dame el primer valor:$"
    msg2 db 10,13,"dame el segundo valor:$"
    msg3 db 10,13,"Suma=$"   
.code
 begin proc far
    ;direccionar al segmento de datos
    mov ax,@data
    mov ds,ax
     
    ;solicita el primer dato
    mov ah,09
    lea dx,msg1
    int 21h
    ;se lee el primer valor
    mov ah,01 ;servicio 01 para leer and save in al
    int 21h
    sub al,30h ;convierte al caracter en numero
    mov n1,al
     
    ;solicita el otro valor
    mov ah,09
    lea dx,msg2
    int 21h
    ;lee el segundo valor
    mov ah,01
    int 21h
    sub al,30h ;convierte el caracter a num
    mov n2,al
    ;operacion
    mov al,n1
    add al,n2
    add al,30h ;convierte a caracter
    mov suma,al
    mov ah,09
    lea dx,msg3
    int 21h
     
    ;imprime el caracter con el servicio
    ;02 de la int 21h
     
    mov ah,02
    mov dl,suma ;se debe enviar a dl para imprimir
    int 21h
    ;instrucciones para cerrar el programa
    mov ah,4ch
    int 21h
    begin endp
 end
Resultado de este programa, es la petición del programa al usuario por ambos valores y al final lanza el resultado de dicha suma.


RESTA DE NÚMEROS EN EMU8086
En esta entrada les presento el programa que anteriormente habíamos visto de un vídeo, pero esta modificado de manera que en lugar de realizar una suma en el programa y los registros, el programa tomara dos valores de teclado dados por el usuario y nos imprimirá el resultado en pantalla con un mensaje.

CÓDIGO:

.model small
.stack 64
.data
   
;declarando variables globales
numero1 db 0
numero2 db 0
resta db 0
msjn1 db 10,13, "INGRESE EL PRIMER NUMERO A RESTAR=  ",'$';ingrese n1
msjn2 db 10,13, "INGRESE EL SEGUNDO NUMERO A RESTAR=  ",'$';ingrese n2
;mensaje para mostrar los resultados
  
msjnR db 10,13, "LA RESTA DE LA OPERACION DADA ES=  ",'$'
  
.code
begin proc far  
     
     
    ;direccionamiento del procedimiento
    mov ax, @data
    mov ds,ax  
     
     
    ;solicitar del teclado numero 1
     
    mov ah, 09
    lea dx, msjn1
    int 21h
    mov ah, 01
    int 21h
    sub al, 30h
    mov numero1,al  
     
     
    ;solicitar del teclado numero 2
     
    mov ah, 09
    lea dx, msjn2
    int 21h
    mov ah, 01
    int 21h
    sub al, 30h
    mov numero2,al
     
    ;operaciones aritmeticas
                   
     
    ;RESTA
    mov al,numero1
    sub al,numero2
    mov resta,al
     
  
    ;mostrando la resta
    mov ah,09
    lea dx,msjnR
    int 21h
    mov dl,resta
    add dl,30h
    mov ah,02
    int 21h
    
   
    ;cierre del programa
    mov ah,4ch
    int 21h
     
    begin endp
end



CALIFICACIÓN, COMPARA SI ESTA O NO REPROBADO
EMU8086

En esta entrada les traigo un programa visto en clase en donde ingresando una calificación al sistema, nos mostrara un mensaje si la calificacion es aprobatoria o no.
Anteriormente habíamos visto como podíamos realizar sumas o restas con numeros de un solo dígito, pues en esta ocasión la calificación es de dos dígitos, por lo que en la sintaxis se ira explicando como es que esto funciona.

CÓDIGO:

.model small
.stack 64
.data ;seccion de variables 
   msg1 db "Dame una calificacion (Seguida de un enter):.$"
   aprobado db 13,10,"Aprobado.$"
   reprobado db 13,10,"Reprobado.$"
   VAR1 dw ?,"$"
   VAR2 dw ?,"$"
   VAR3 dw ?,"$"
    
    
.code ;inicia el segmento del programa
RESULTADO PROC FAR
    MOV AX,@DATA ;Inicio del programa
    MOV DS,AX
    ;Desplegar primer mensaje
     
    MOV AH,09
    lea DX,msg1
    int 21h
    ;Pedir un numero
    MOV AH,01
    int 21h
    MOV VAR1,AX
    ;Pedir un segundo numero
    MOV AH,01
    int 21h
    MOV VAR2,AX
    ;Pedir un tercer numero
    MOV AH,01
    int 21h
    MOV VAR3,AX
    ;Momento de evaluar la calificacion
     
    CMP AL,13           ;Comparacion
    JE CONTINUE   ;Salta si es igual
    JMP MAYOR      ;salto incondicional
    ;Inicia funcion
    CONTINUE:
        MOV AX,VAR1
        CMP AL,037h  ;7 es 37 en ascii
        JGE MAYOR   ;salta si es mayor o igual
        JMP MENOR   ;salto incondicional
         
    MAYOR:
        MOV AH,09
        lea dx,aprobado
        int 21h
        JMP SALIR
         
    MENOR:
        MOV AH,09
        lea dx,reprobado
        int 21h
        JMP SALIR
         
    SALIR:
        MOV AX,4CH
        int 21h
         
    RESULTADO ENDP
END RESULTADO
Como verán en la sintaxis, estamos guardando tres valores en nuestras variables. Al ingresar nuestra calificación(80), guardamos el 8 en código ascii en una variable, el 0 en otra variable(también en ascii) y finalmente el enter en la ultima variable. Para comparar, tomamos de base el 70 en codigo ascii para así saber a cual de las dos funciones(menor o mayor) ira nuestro programa al comparar con el valor que ya le hemos dado.



PROGRAMAS DE EJEMPLOS

En esta ocasión dejare la sintaxis de dos programas que hemos visto en clase para analizar su funcionamiento y el uso de los registros dentro de ambos programas.

CÓDIGO 1:

org 100h
mov ax,100 ;pone al registro ax un valor de 9
mov bx,5 ;pone al registro bx un valor de 9
div bx ;divide lo que hay en ax, entre lo que se encuentra en bx
ret
Guarda en la parte alta del registro ax, el 100 en hexadecimal
Guarda en la parte alta del registro bx, el 5 en hexadecimal
Finalmente, realiza la operacion de division con lo que hay en bx, guardando el resultado en la parte alta del registro ax en hexadecimal.
CÓDIGO 2:
Para mayor comprensión(ya que este si es un programa mas extenso) he dejado en la sintaxis comentarios para así saber que se esta haciendo en cada una de las partes del código.
org 100h
.model small
.stack 64 ;segmento de pila
.data
    msg db "Ingrese su edad'$"
    msg1 db 13,10,"Eres mayor de edad.$"
    msg2 db 13,10,"Eres menor de edad.$"
    num1 db 0 ;Variable para la edad
    diez db 10 ;variable para poder imprimir dos caracteres y multiplicar el valor por 10   
     
.code ;Inicio del programa 
    inicio proc Far
    MOV AX,@DATA
    MOV DS,AX
     
    ;Despliega el mensaje 1
    MOV AH,09
    lea DX,msg
    int 21h
     
    ;Ingresa el numero
    MOV AH,01
    int 21h
    ;MOV num1,AX
    sub al,30h ;Convirtiendo a valor
    mul diez ;se multiplica el numero ingresado para las decenas
    mov num1,al ;se pasa a num la multiplicacion  
     
    ;Ingresa otro numero
    mov ah,01
    int 21h
    sub al,30h
    add num1,al ;se suma a las decenas 
    mov al,num1
     
    ;Momento de evaluar 
    CMP AL,18
    JGE MAYOR ;En caso de ser mayor brinca aqui
    JMP MENOR ;en caso de ser menor de edad
     
     
    MAYOR:
    MOV AH,09
    lea DX,msg1
    int 21h
    jmp fin
     
     
    MENOR:
    MOV AH,09
    lea DX,msg2
    int 21h
    jmp fin
     
     
    fin:
    mov ax,4c00h
     
     
    inicio endp
    end
ret


Ejecución:


VÍDEO DE SUMA DE DOS NÚMEROS CON LIBRERIA. Explicacion de libreria emu8086.inc
Para usar cualquiera de las funciones de Emu8086.inc se debe colocar la siguiente linea al inicio del programa en donde se vaya a implementar: include 'emu8086.inc'

Emu8086.inc define los siguientes macros:

PUTC char: imprime un solo caracter
GOTOXY col, row: coloca el cursor en las coordenadas solicitadas
PRINT string: Imprime una cadena
PRINTN string: Imprime una cadena y tras imprimirla hace un salto de linea.




Código:



;Creador por Cuevas Villafranco ivan enrique
name "Suma dos numeros"
include "emu8086.inc"
org 100h
.data
suma db 2 dup (?)  ;Creamos un arreglo llamado suma de 2 espacios de tipo byte
.code
Sumas proc      ;Se crea un proceso de sumas y se piden los numeros
printn " "
print "Introduce el primer numero ==>"
call scan_num
   mov suma[0],cl   ;guarda el valor en cl,y lo manda al arreglo
    printn " "
    print "Introduce el segundo numero ==>"
    call scan_num   ;
    mov suma[1],cl
    printn " "
    xor ax,ax     ;se limpia el registro ax
    add al,suma[0] ;se manda la suma al registro al
    add al,suma[1] ;se manda para poder imprimir
    printn " "
    print "La suma es: "
    call print_num
Sumas endp
exit:
    printn " "
    printn " "
    print "Presiona enter para salir..";etiqueta con instruccion para salir del programa
    mov ah,0
    int 16h
    ret
   define_print_string   ;apartado de definicion de comandos emu8086.inc
define_print_num
   define_print_num_uns
   define_scan_num          
   end


Al iniciar le asignamos un nombre al programa, en esta ocasion sera "Suma de dos numeros"
Posteriormente, colocamos la libreria utilizada en esta ocasion que sera la emu8086.inc, despues de ello se inicia el programa como regularmente se hace con org 100h


En la sección de datos, se va a declarar un arreglo llamado suma de dos espacios de tipo byte,después de ello iniciamos con el código de nuestro programa.
Iniciamos creando un procedimiento llamado suma y comenzamos a pedir los números.
Mandamos a imprimir mensajes por medio de la instrucción print, posteriormente por medio de una llamada, usamos la función scan_num que funciona para la obtención de datos ingresados por el usuario.
Guardamos el valor en la parte alta del registro cx, y posteriormente lo mandamos al arreglo que habíamos creado en un inicio. (Hacemos lo mismo con el segundo numero a ingresar).
Una vez que tenemos nuestros dos valores en el arreglo, limpiamos el registro ax que utilizaremos para poder realizar la suma. Mandamos lo que hay en la posición 0 de nuestro arreglo suma a la parte alta de ax para que se sume con lo que hay en el(como se limpio, por ende no debe haber nada), y posteriormente hacemos lo mismo con la posición 1 de nuestro arreglo.
Finalmente mandamos a imprimir el resultado de nuestra suma con la función print_num que nos imprime en pantalla el contenido del registro ax.(se termina el procedimiento).


Iniciamos la función exit, que nos servirá únicamente para darle fin a nuestro programa.
Utilizando la interrupción 16h(invoca los servicios estándar del teclado), y el servicio 0(leer carácter de teclado) en el registro ah.(al momento de dar enter, se finaliza el programa)
Finalmente tenemos el apartado de definición de comandos que se están utilizando en este programa,para escanear e imprimir números.


Ejecución:














Registros de banderas (Video)

Es un registro de 16 bits, de los cuales 9 de ellos sirven para indicar el estado actual de la maquina y el resultado del procesamiento.
Aquí inserto una representación de esto, así como la explicación de que hace cada una de las banderas que se tienen para el estado actual de maquina y su resultado.