Unidad 2 – Programación básica


Competencia específica
Conocer y utilizar las principales instrucciones del lenguaje ensamblador, para realizar determinadas aplicaciones de interfaz. Listar las principales instrucciones de programación en lenguaje ensamblador.
img9.jpg

2.1 Ensamblador (y ligador) a utilizar.


Aunque la sintaxis entre ensambladores es parecida, es necesario mencionar que los ejemplos de este manual están hechos para las siguientes herramientas:
Turbo Assembler
Turbo Assembler o TASM es un ensamblador desarrollado por Borland el cual además de permitir ensamblar código MASM (Microsoft Macro Assembler) en su modo de compatibilidad, es capaz de soportar programación orientada a objetos desde la versión 3.0 y de generar código para 16 o 32 bits.
La característica más importante de Turbo Assembler es que es compatible con lenguajes de alto nivel, por ejemplo: Turbo Pascal, Turbo Basic, Turbo C, Turbo C++.
Turbo Linker
Turbo Linker o T-Link es el enlazador (ligador) incluido con Turbo Assembler, el cual se encarga de generar el código ejecutable a partir del código objeto generado por TASM.
Para descargar:

2.2 Ciclos numéricos.


Como en cualquier otro lenguaje de programación, hay ocasiones en las que es necesario hacer que el programa no siga una secuencia lineal, sino que repita varias veces una misma instrucción o bloque de instrucciones antes de continuar con el resto del programa, es para esto que se utilizan los ciclos.
Existen 5 tipos de ciclos predefinidos en ensamblador, aunque también se pueden crear ciclos personalizados por medio de instrucciones de salto las cuales se verán en la sección 2.6 de este manual.
Los ciclos predefinidos de ensamblador son los siguientes:
LOOP:
Esta función decrementa el valor del registro contador CX, si el valor contenido en CX es cero ejecuta la siguiente instrucción, en caso contrario transfiere el control a la ubicación definida por la etiqueta utilizada al momento de declarar el ciclo.
Ejemplo:
  • mov cx,25 :    Número de veces que se repetirá el ciclo, en este caso 25.
  • ciclo:  Etiqueta que se utilizará como referencia para el ciclo loop.
  • int 21h: Instrucción contenida dentro del ciclo (puede contener más de una instrucción).
  • loop:  Ciclo loop que transferirá el control a la línea de la etiqueta ciclo en caso de que CX no sea cero.
REPORT THIS AD
LOOPE:
Esta función decrementa el valor del registro contador CX, si el valor contenido en CX es cero y ZF es diferente de uno ejecuta la siguiente instrucción, en caso contrario transfiere el control a la ubicación definida por la etiqueta utilizada al momento de declarar el ciclo.
Ejemplo:
  • ciclo: Etiqueta que se utilizará como referencia para el ciclo loope.
  • int 21h: Instrucción contenida dentro del ciclo (puede contener más de una instrucción).
  • loope: Ciclo loope que transferirá el control a la línea de la etiqueta ciclo en caso de que CX no sea cero y ZF sea igual a uno.
LOOPNE:
Esta función decrementa el valor del registro contador CX, si el valor contenido en CX es cero y ZF es diferente de cero ejecuta la siguiente instrucción, en caso contrario transfiere el control a la ubicación definida por la etiqueta utilizada al momento de declarar el ciclo, esta es la operación contraria a loope.
Ejemplo:
  • ciclo: Etiqueta que se utilizará como referencia para el ciclo loopne.
  • int 21h: Instrucción contenida dentro del ciclo (puede contener más de una instrucción).
  • loopne: Ciclo loopne que transferirá el control a la línea de la etiqueta ciclo en caso de que CX no sea cero y ZF sea igual a cero.
REPORT THIS AD
LOOPZ:
Esta función decrementa el valor del registro contador CX, si el valor contenido en CX es cero y ZF es diferente de uno ejecuta la siguiente instrucción, en caso contrario transfiere el control a la ubicación definida por la etiqueta utilizada al momento de declarar el ciclo.
Ejemplo:
  • ciclo: Etiqueta que se utilizará como referencia para el ciclo loopz.
  • int 21h: Instrucción contenida dentro del ciclo (puede contener más de una instrucción).
  • loopz: Ciclo loopz que transferirá el control a la línea de la etiqueta ciclo en caso de que CX no sea cero y ZF sea igual a uno.
LOOPNZ:
Esta función decrementa el valor del registro contador CX, si el valor contenido en CX es cero y ZF es diferente de cero ejecuta la siguiente instrucción, en caso contrario transfiere el control a la ubicación definida por la etiqueta utilizada al momento de declarar el ciclo, esta es la operación contraria a loopz.
Ejemplo:
  • ciclo: Etiqueta que se utilizará como referencia para el ciclo loopnz.
  • int 21h: Instrucción contenida dentro del ciclo.
  • loopnz: Ciclo loopnz que transferirá el control a la línea de la etiqueta ciclo en caso de que CX no sea cero y ZF sea igual a cero.
REPORT THIS AD
Resultado de imagen para ciclos numéricos.
2.3 Captura básica de cadenas.
Dentro del lenguaje ensamblador no existe el tipo de dato cadena (string en otros lenguajes), por lo que para utilizarla es necesario tratar a las cadenas como un conjunto de caracteres reservados bajo el nombre de una sola variable.
El lenguaje ensamblador cuenta con instrucciones que por su naturaleza sirven para el manejo de cadenas, estas son:
MOVSB:
Mueve un byte desde una localidad de memoria hasta otra.
MOVSW:
Mueve una palabra desde una localidad de memoria hasta otra.
LODSB:
Carga en la parte baja del registro acumulador (AL) el valor de la localidad de memoria determinada por DS:SI.
LODSW:
Carga en el registro acumulador (AX) el valor de la localidad de memoria determinada por DS:SI
2.4 Comparación y prueba.
La comparación y prueba son instrucciones especiales con las que cuenta el microprocesador, estas son CMP y TEST respectivamente.
Comparación (CMP):
Esta instrucción compara los dos valores que se le den como parámetros y modifica las banderas de signo (SF), de cero (ZF) y de acarreo (CF) según sea necesario.
Ejemplo:
CMP ah,10h: Compara el valor almacenado en el registro ah con el valor 10 hexadecimal.
Prueba (TEST):
Verifica que los valores que se le introduzcan como parámetros sean iguales relizando la operación lógica AND, no almacena ningún resultado pero modifica banderas según sea necesario.
Ejemplo:
TEST al, 1: Verifica que el valor almacenado en al sea 1.

2.5 Saltos.


Los saltos son instrucciones que permiten al programador cambiar el orden de ejecución del programa según sea necesario, dentro de ensamblador existen dos tipos de salto principales: condicionales e incondicionales.
Saltos Incondicionales:
Los saltos incondicionales se utilizan mediante la instrucción JMP, la cual transfiere el control a la línea especificada después de la palabra JMP, la cual puede ser un valor directo o una etiqueta.
También se puede contar como un salto incondicional la instrucción CALL, la cual llama una procedimiento y al terminarla devuelve el control a la línea siguiente de donde se inicio la llamada a procedimiento, pero eso se ve con más detalle en la sección 3.1.
Ejemplo:
  • Salto: Etiqueta a la que se hará referencia para el salto incondicional.
  • JMP Salto: Instrucción que indica que el flujo del programa continuara desde la ubicación de la etiqueta Salto.
Saltos Condicionales:
Los saltos condicionales transfieren el control del programa a la ubicación que se les dé como parámetro si al hacer una comparación se cumple la condición establecida en el salto, los saltos condicionales son los siguientes:
JA (Jump if Above):
Salta cuando el valor es superior, su condición es equivalente al salto JNBE (Jump if Not Below or Equal).
JAE (Jump if Above or Equal):
Salta cuando el valor es superior o igual, su condición es equivalente al salto JNB (Jump if Not Below).
JB (Jump if Below):
Salta cuando el valor es menor, su condición es equivalente al salto JNAE (Jump if Not Above or Equal).
JBE (Jump if Below or Equal):
Salta cuando el valor es menor o igual, su condición es equivalente al salto JNA (Jump if Not Above).
JE (Jump if Equal):
Salta cuando el valor es igual.
JZ (Jump if Zero):
Salta cuando el valor es cero.
JNE (Jump if Not Equal):
Salta cuando el valor no es igual.
JNZ (Jump if Not Zero):
Salta cuando el valor no es cero.
JG (Jump if Greater):
Salta cuando el valor es mayor, su condición es equivalente al salto JNLE (Jump if Not Less or Equal).
JGE (Jump if Greater or Equal):
Salta cuando el valor es mayor o igual, su condición es equivalente al salto JNL (Jump if Not Less).
JL (Jump if Less):
Salta cuando el valor es menor, su condición es equivalente al salto JNGE (Jump if Not Greater or Equal).
JLE (Jump if Less or Equal):
Salta cuando el valor es menor o igual, su condición es equivalente al salto JNG (Jump if Not Greater).
Ejemplo:
  • Salto:  Etiqueta a la que se hará referencia para el salto condicional.
  • CMP al, bl: Comparación entre el valor almacenado en al y el almacenado en bl.
  • JG Salto: Instrucción que indica que el flujo del programa continuara desde la ubicación de la etiqueta Salto si el valor de al es mayor al de bl.

2.6 
Ciclos condicionales
LOOP etiqueta
La instrucción loop decrementa CX en 1, y transfiere el flujo del programa a la etiqueta dada como operando si CX es diferente a 1.
Instrucción LOOPE
Propósito: Generar un ciclo en el programa considerando el estado de ZF

LOOPE etiqueta 
Esta instrucción decrementa CX en 1. Si CX es diferente a cero y ZF es igual a 1, entonces el flujo del programa se transfiere a la etiqueta indicada como operando.

Instrucción LOOPNE
Propósito: Generar un ciclo en el programa, considerando el estado de ZF


LOOPNE etiqueta 
Esta instrucción decrementa en uno a CX y transfiere el flujo del programa solo si ZF es diferente a 0.


2.7- Incremento y decremento y 


2.8-Captura de cadenas con formato

2.7-Incremento y decremento
Son las instrucciones más básicas a la hora de hacer operaciones con registros: INC

incrementa el valor de un registro, o de cualquier posición en memoria, en una unidad, y  DEC lo decrementa.

Instrucción INC

INC AX

Incrementa en uno el valor de AX

IN WORD PTR

Incrementa la palabra situada en CS.

Instrucción DEC

DEC AX

Decremento AX, le resta uno.

DEC WORD PTR

Decrementa la palabra situada en CS


2.8-Captura de cadenas con formato
El capturar cadenas con formato permite el movimiento, comparación o búsqueda rápida entre bloques de datos, las instrucciones son las siguientes:

MOVC:

Esta instrucción permite transferir un carácter de una cadena.

MOVW:

Esta instrucción permite transferir una palabra de una cadena.

CMPC:

Este comando es utilizado para comparar un carácter de una cadena.

CMPW:

Esta instrucción es utilizada para comparar una palabra de una cadena.

SCAC:

Esta instrucción permite buscar un carácter de una cadena.

SCAW:

Esta instrucción se utiliza para buscar una palabra de una cadena.

LODC:

Esta instrucción permite cargar un carácter de una cadena.

LODW:

Esta instrucción es utilizada para cargar una palabra de una cadena.

STOC:

Esta instrucción permite guardar un carácter de una cadena.

STOW:

Esta instrucción es utilizada para guardar  una palabra de una cadena.

2.9-Instrucciones aritmeticas



.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
  

  
   ;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   







2.10.- Manipulación de la pila

La pila es un grupo de localidades de memoria que se reservan con la finalidad de proporcionar un espacio para el almacenamiento temporal de información.

La pila de los programas es del tipo LIFO (Last In First Out, Ultimo en entrar, Primero en salir).
Para controlar la pila el microprocesador cuenta con dos instrucciones básicas:
Push (Meter) y Pop (sacar).

El formato de estas instrucciones es el siguiente:
  • Push operando
  • Pop operando 
Cuando se ejecuta la instrucción Push, el contenido del operando se almacena en la ultima posición de la pila. Por ejemplo, si AX se carga previamente con el valor 5, una instrucción Push AX almacenaría el valor 5 en la ultima posición de la pila.

Por otro lado la instrucción Pop saca el último dato almacenado en la pila y lo coloca en el operando.
Siguiendo el ejemplo anterior, la instrucción Pop BX obtendría el número 5 y lo almacenaría en el registro BX. El siguiente ejemplo muestra como implementar la instrucción XCHG por medio de las instrucciones Push y Pop. Recuerde que la instrucción XCHG intercambia el contenido de sus dos operandos. 

.COMMENT
Programa: PushPop.ASM
Descripción: Este programa demuestra el uso de las instrucciones para el manejo de la pila, implementando la instrucción XCHG con Push y Pop
MODEL tiny
.CODE
Inicio: ;Punto de entrada al programa
Mov AX,5 ;AX=5
Mov BX,10 ;BX=10
Push AX ;Pila=5
Mov AX,BX ;AX=10
Pop BX ;BX=5
Mov AX,4C00h ;Terminar programa y salir al DOS
Int 21h ;
END Inicio
END
-ROT (a b c – c a b) Rota hacia atrás. 
-2ROT (ab cd ef – ef ab cd) Rota hacia atrás. 
NIP ( a b – b) Quita a de la pila. 
OUTK (... n -- ..) Elimina el elemento n. 
TUCK (a b -- b a b) Inserta una copia de b. 
2?DUP (ab – ab ab) Duplica si ab <> 0. 
2DROP (ab -- ) Elimina 2 de encima. 
2DUP ( ab – ab ab) Duplica los elementos. 
2NIP (ab cd – cd) Elimina elementos. 
2OUTK (::: n -- ::) Elimina el elemento n 
2OVER (ab cd – ab cd ab) Inserta una copia de ab. 
2PICK (:: n -- :::) Copia el elemento n 
encima de la pila. 
2ROLL (::: n -- :::) Quita el elemento n y 
lo deja arriba de la pila. 
2ROT (ab cd ef – cd ef ab) Rota los elementos 
2TUCK (ab cd – cd ab cd) Inserta una copia de cd. 
2SWAP (ab cd – cd ab) Rota los elementos.

2.11.- Obtención de cadena con representación decimal

En este modo, los datos son proporcionados directamente como parte de la instrucción.

Ejemplo:

Mov AX,34h ;

Copia en AX el número 34h hexadecimal Mov CX,10 ;

Copia en CX el número 10 en decimal
.COMMENT
Programa: PushPop.ASM
Descripción: Este programa demuestra el uso de las instrucciones para el manejo de la pila, implementando la instrucción XCHG con Push y Pop
MODEL tiny
.CODE

Inicio: ;Punto de entrada al programa
Mov AX,5 ;AX=5
Mov BX,10 ;BX=10
Push AX ;Pila=5
Mov AX,BX ;AX=10
Pop BX ;BX=5
Mov AX,4C00h ;Terminar programa y salir al DOS
Int 21h ;
END Inicio
END

Referencias Bibliograficas:

http://documents.mx/documents/unidad-2-lenguaje-de-interfaz.html
http://itpn.mx/recursosisc/6semestre/lenguajesdeinterfaz/Unidad%20II.pdf


2.12.- Instrucciones lógicas

AND





Referencias Bibliograficas:
http://documents.mx/documents/unidad-2-lenguaje-de-interfaz.html
http://itpn.mx/recursosisc/6semestre/lenguajesdeinterfaz/Unidad%20II.pdf


2.13.- Desplazamiento y rotación












De manera similar a RCR, RCL también provoca que la bandera de acarreo participe en la rotación. Cada bit que se desplaza fuera por la izquierda se mueve al CF, y el bit del CF se mueve a la posición vacante de la derecha. Puede usar la instrucción JC (salta si hay acarreo) para comprobar el bit rotado hacia la CF en el extremo de una operación de rotación. Tomado de: Tutorial de Lenguaje Ensamblador

Referencias Bibliograficas:
http://documents.mx/documents/unidad-2-lenguaje-de-interfaz.html
http://itpn.mx/recursosisc/6semestre/lenguajesdeinterfaz/Unidad%20II.pdf
https://es.slideshare.net/KILLERMSTR/prez-camacho-jess-asmeth
http://lenguajes-interfaz-2013.blogspot.mx/2014/03/unidad-ii-programacion-basica.html

2.14.- Obtención de una cadena con la representación hexadecimal

La conversión entre numeración binaria y hexadecimal es sencilla. Lo primero que se hace para una conversión de un número binario a hexadecimal es dividirlo en grupos de 4 bits, empezando de derecha a izquierda. En caso de que el último grupo (el que quede más a la izquierda) sea menor de 4 bits se rellenan los faltantes con ceros. 

Tomando como ejemplo el número binario 101011 lo dividimos en grupos de 4 bits y nos queda: 

10; 1011

 Rellenando con ceros el último grupo (el de la izquierda):

0010; 1011 

después tomamos cada grupo como un número independiente y consideramos su valor en decimal: 

0010 = 2; 1011 = 11 

Pero como no podemos representar este número hexadecimal como 211 porqué sería un error, tenemos que sustituir todos los valores mayores a 9 por su respectiva representación en hexadecimal, con lo que obtenemos: 

2BH (Donde la H representa la base hexadecimal) 

Para convertir un número de hexadecimal a binario solo es necesario invertir estos pasos: se toma el primer dígito hexadecimal y se convierte a binario, y luego el segundo, y así sucesivamente hasta completar el número. 

Referencias Bibliograficas:

http://documents.mx/documents/unidad-2-lenguaje-de-interfaz.html
http://itpn.mx/recursosisc/6semestre/lenguajesdeinterfaz/Unidad%20II.pdf

2.15.- Captura y almacenamiento de datos numéricos

Esta representación esta basada en la notación científica, esto es, representar un número en dos partes: su mantisa y su exponente. 

Poniendo como ejemplo el número 1234000, podemos representarlo como 1.123*10^6, en esta última notación el exponente nos indica el número de espacios que hay que mover el espacio hacia la derecha para obtener el resultado original. 

En caso de que el exponente fuera negativo nos estaría indicando el número de espacios que hay que recorrer el punto decimal hacia la izquierda para obtener el original. 

Proceso de creación de un programa 

Para la creación de un programa es necesario seguir cinco pasos: diseño del algoritmo, codificación del mismo, su traducción a lenguaje máquina, la prueba del programa y la depuración.

En la etapa de diseño se plantea el problema a resolver y se propone la mejor solución, creando diagramas esquemáticos útilizados para el mejor planteamiento de la solución. 

 La codificación del programa consiste en escribir el programa en algún lenguaje de programación; en este caso específico en ensamblador, tomando como base la solución propuesta en el paso anterior.

 La traducción al lenguaje máquina es la creación del programa objeto, esto es, el programa escrito como una secuencia de ceros y unos que pueda ser interpretado por el procesador.

 La prueba del programa consiste en verificar que el programa funcione sin errores, o sea, que haga lo que tiene que hacer. 

Referencias Bibliograficas:

http://documents.mx/documents/unidad-2-lenguaje-de-interfaz.html
http://itpn.mx/recursosisc/6semestre/lenguajesdeinterfaz/Unidad%20II.pdf





Comentarios

Entradas populares de este blog

Resumen de Lenguaje ensamblador del procesador