You are on page 1of 16

UNIVERSIDAD DE EL SALVADOR

FACULTAD DE INGENIERIA Y ARQUITECTURA


ESCUELA DE INGENIERIA ELECTRICA
SISTEMAS DIGITALES PROGRAMABLES

19 DE MAYO DE 2017
LAB05: USO DEL
LENGUAJE
ENSAMBLADOR CON EL
COMPLILADOR C.

PORCENTAJE NOTA
1) INTRODUCCION 5%
2) OBJETIVOS 5%
3) MARCO TEORICO 10%
4) DESARROLLO DE LA PRACTICA 10%
5) ASIGNACIONES 40%
ASIGNACION 1 8%
ASIGNACION 2 8%
ASIGNACION 3 8%
ASIGNACION 4 8%
ASIGNACION 5 8%
CONCLUSIONES 30%
NOTA FINAL

ESTUDIANTES:
Tabla de contenido

INTRODUCCION ................................................................................................................................... 2

OBJETIVOS ........................................................................................................................................... 3

MARCO TEORICO ................................................................................................................................. 4

DESARROLLO DE LA PRÁCTICA ............................................................................................................ 5

ASIGNACIONES .................................................................................................................................... 8

CONCLUSIONES ................................................................................................................................. 15

1
INTRODUCCION.

El lenguaje ensamblador sirve para muchos propósitos, como mejorar la velocidad del
programa, reducir la memoria necesaria y supervisar el hardware. Pero hoy día, pocos
programas están escritos completamente en ensamblador. Los compiladores son muy buenos
en convertir código de alto nivel en un código de máquina eficiente. Ya que es mucho más
fácil escribir código en un lenguaje de alto nivel, es más popular. Además, el código de alto
nivel es mucho más portátil que el ensamblador. Cuando se usa ensamblador, se usa a
menudo solo para pequeñas partes de código. Esto se puede hacer de dos maneras: llamando
rutinas de ensamblador desde C o ensamblado en línea.

Se puede utilizar el ensamblado en línea para incrustar instrucciones de lenguaje de


ensamblado directamente en los programas de origen C y C++ sin realizar pasos adicionales
de ensamblado y vínculo. El ensamblador alineado se compila en el programa compilador,
por lo que no es necesario un ensamblador independiente como Microsoft Macro Assembler
(MASM). Se puede usar esta manera mencionada usando la sentencia “asm” que permite
incluir código ensamblado C, utilizando los mnemónicos normales del ensamblador. Sin
embargo, el uso de esta posibilidad está más o menos limitado según la versión del
compilador. Como otra opción se tiene ensamblar el código y luego enlazarlo a la
compilación del código en C como llamado de rutina. Para esta práctica de laboratorio se
estudian los pasos a seguir para la combinación de lenguaje ensamblador y lenguaje de alto
nivel C, a través de la herramienta Borland.

2
OBJETIVOS

General:

 Conocer las estructuras básicas para la combinación del lenguaje ensamblador con
lenguaje de alto nivel C, así como las diferentes maneras en las que se puede usar esta
mezcla para la creación de programas más eficientes.

Específicos:

 Hacer uso de la herramienta Borland para la combinación de lenguaje ensamblador y


lenguaje C.

 Utilizar como método principal para la combinación de ambos lenguajes el incluir


código ensamblador dentro del programa escrito en código C.

3
MARCO TEORICO.

1. Incluir rutinas en ensamblador desde C.

La palabra ASM

Este es un mecanismo de escape que permite escribir código ensamblador para el hardware
dentro de un programa en C. A menudo es capaz de referenciar variables C dentro del código
ensamblador, lo que significa que se puede comunicar fácilmente con el código C y limitar
el código ensamblador a lo necesario para ajustes eficientes o para utilizar instrucciones
especiales del procesador. La sintaxis exacta que se debe usar cuando se escribe en lenguaje
ensamblador es dependiente del compilador y se puede encontrar en la documentación del
compilador. La sentencia ASM permite incluir código ensamblador dentro del programa C,
utilizando los mnemónicos normales del ensamblador. Sin embargo, el uso de esta
posibilidad está más o menos limitado según la versión del compilador. En Turbo C 2.0, los
programas que utilizan este método es necesario salir a la línea de comandos para compilarlos
con el tradicional compilador de línea, lo cual resulta poco atractivo. Sin embargo, es a partir
del Borland C++ cuando se puede trabajar a gusto: en concreto, la versión Borland C++ 2.0
permite ensamblar sin rodeos código ensamblador incluido dentro del listado C. El único
inconveniente es la limitación del hardware disponible: para un PC/XT, el Turbo C 2.0 es el
único compilador aceptablemente rápido. Sin embargo, en un 286 es más recomendable el
Turbo C++, mientras que en un 386 modesto (o incluso en un 286 potente) resulta más
interesante emplear el Borland C++ 2.0: las versiones 3.X de este compilador son las más
adecuadas para un 486 o superior (bajo DOS). Como ejemplo del uso de esta sentencia se
muestra las siguiente instrucciones que permiten cambiar el modo de video de la pantalla a
un modo VGA estándar con código ensamblador, es mucho más sencillo:

4
DESARROLLO DE LA PRÁCTICA

Practica 1: Compile el código apéndice A con Borland C:


Código apéndice A:

1. #include <stdio.h>
2. /*
3. Este ejemplo muestra como combinar el codigo en lenguaje
4. Ensamblador con codigo C
5. Realiza las operaciones basicas suma, resta, multiplicacion y
6. Division con dos numeros de 8 bits
7. */
8. int main()
9. {
10. int dato1, dato2, suma, resta, multiplicacion,division;
11. printf("Multiplicación de dos numeros \n");
12. printf("\nPrimer numero: ");
13. scanf("%d", &dato1);
14. printf("Segundo número: ");
15. scanf("%d", &dato2);
16.
17. asm{
18. push dx //Introduciendo los registros a la
pila
19. push cx
20. push bx
21. push ax
22.
23. //Suma
24. mov ax,dato1
25. add ax,dato2
26. mov suma,ax
27.
28. //Resta
29. mov ax,dato1
30. sub ax,dato2
31. mov resta,ax
32.
33. //Multiplicacion
34. mov ax,dato1
35. imul dato2
36. mov multiplicacion , ax
37.
38. //Division
39. mov ax,dato1
40. div dato2
41. mov ah,0
42. mov division,ax
43.
44. pop ax
45. pop bx
46. pop cx

5
47. pop dx //Devolviendo los registros de la
pila
48.
49. }
50. printf("\nSuma: %d\n", suma);
51. printf("Diferencia: %d\n",resta);
52. printf("Producto: %d\n", multiplicacion);
53. printf("Cociente: %d\n", division);
54. return 0;
55. }

Al compilar el codigo anterior en Borland C se puede observar que el programa realiza las
cuatro operaciones basicas, con dos numeros ingresados por el usuario como muestra la
figura 1.

Fig. 1: Compilación del código del Apéndice A.

Practica 2: Compile el código del Apéndice B con Borlad C.


Código apéndice B:

1. #include <stdio.h>
2.
3. main()
4. {
5. //El siguiente programa representa un ejemplo de una
6. //transmision de bytes de datos utilizando sus bits de paridad
7. //aunque los datos solo se miran en pantalla, en la
8. //practica se utiliza un puerto y la paridad para detectar
9. //errores en la recepcion.
10.
11. int byte1,byte2, paridad;
12. printf("introdusca el primer byte en hexadecimal \n");
13. scanf("%x", &byte1);
14. printf("introdusca el segundo byte en hexadecimal \n");
15. scanf("%x", &byte2);

6
16.
17. asm{
18. push ax //Guardamos los registros que usaremos
19. push bx //Por razones de seguridad
20. mov paridad,0
21. mov ax,0
22. mov bx,byte1
23. and bx,0ffh //Operacion logica que activa la bandera de
paridad
24. pushf //Guardamos el registro de banderas en la pila
25. pop ax //Y lo recuperamos sin alterarlo
26. and ax,04h //Probamos la bandera de paridad
27. cmp ax,04h
28. jne seguir
29. inc paridad //Incrementamos el resultado si hay bit de
paridad
30. }
31. seguir:
32. asm{
33. mov bx,byte2 //Repetimos lo mismo que hicimos
34. and bx,0ffh //con el primer byte
35. pushf
36. pop ax
37. and ax,04h
38. cmp ax,04h
39. jne final
40. add paridad, 2h
41. }
42. final:
43. asm{
44. pop bx //Recuperacion de los registros antes
45. pop ax //De terminar las lineas de ensamblador
46. }
47. printf("\n byte con la paridad junto a los dos bytes
originales:\n");
48. printf("%X%X%X\n",paridad,byte2,byte1);
49. return 0;
50. }

Fig. 2: Compilación del código del Apéndice B, obtiene paridad para detectar errores de transmisión .

7
ASIGNACIONES.

Asignación 1: Mencionar 5 ventajas de combinar el lenguaje ensamblador con el


compilador C.

 Programar la mayor parte del código en un lenguaje de alto nivel, lo que permite
reducir el tamaño del código en general además de hacerlo más portable y eficiente.

 Hacer uso de lenguaje ensamblador para partes de código donde se necesita la


máxima eficiencia ya que las instrucciones en ensamblador se ejecutan directamente
desde la memoria.

 Permite obtener una mayor velocidad de los programas, esto ya que las instrucciones
de ensamblador se ejecutan más rápidas que las de C, además Permite acceso directo
a hardware para controladores de dispositivos.

 Para el ensamblado en línea no es necesario compilar y enlazar con diferentes


programas para cada lenguaje, ya que incluyendo rutinas del ensamblador en el
lenguaje C por medio de la instrucción asm el compilador de C puede ejecutar el
programa.

 La combinación de lenguaje ensamblador con lenguaje de alto nivel C, permite


obtener programas más eficientes y rápidos.

Asignación 2: Mencione 5 aplicaciones de programas que utilicen lenguaje


ensamblador con el compilador C.

 El kernel de un sistema operativo es un espacio tan cercano al hardware que


únicamente puede ser realizado mediante el uso de ensamblador y lenguaje C. por
ejemplo: Linux, Minix, Hurd, FreeBSD, OpenBSD, y Darwing, el kernel de Mac OS.

 máquinas virtuales de Java y .NET, desarrolladas en C usan instrucciones de código


ensamblador.

 compiladores e intérpretes: se usa C e instrucciones en ensamblador en los de Perl o


PHP, C++ en los lenguajes .NET y en el GCC, y Java para compilarse a sí mismo.

 Programas que requieran acceso directo a periféricos de entrada y salida pueden ser
programados en C con instrucciones de ensamblador.
8
 Aplicaciones que requieran una alta velocidad de ejecución, pueden ser programadas
en C y por medio de instrucciones de ensamblador aumentar la velocidad de
operaciones realizadas. Un ejemplo pueden ser aplicaciones de tabulación de datos
en tiempo real.

Asignación 3: Hacer un programa con 5 posiciones en memoria c/u de las cuales


contienen un dato diferente, el usuario introduce un dato que es comparado con
las posiciones de memoria, si el dato coincide, despliegue un mensaje “USTED ES
GANADOR” de lo contrario despliegue el mensaje “SUERTE LA PROXIMA
VEZ”.Recuerde: Hacer el programa lo más vistoso y práctico para el usuario con
las herramientas conocidas de C o C++, es decir la captura de datos y despliegue
de mensajes, las demás instrucciones deben realizarse con ensamblador.

Descripción del código: El objetivo de este código es hacer un programa C usando


instrucciones de ensamblador por medio de la sentencia asm, como se puede observar todas
las configuraciones de la pantalla se hacen con instrucciones de ensamblador, así como la
validación del dato ingresado para mostrar el mensaje especifico.

Código:

1. #include <stdio.h>
2.
3. int main()
4. {
5. int pos1 = 14, pos2 = 10, pos3 = 50, pos4 = 69, pos5 = 99;
6. int dato;
7. char mensaje1[] = "USTED ES UN GANADOR";
8. char mensaje2[] = "SUERTE LA PROXIMA VEZ";
9.
10. asm{
11. mov ah,06h //Borrando la pantalla
12. mov cx,0000
13. mov dx,2379
14. int 10h
15.
16. mov ah,02H //Posicionando el cursor en pantalla
17. mov dh,10
18. mov dl,10
19. mov bh,0
20. int 10h
21. }
22.
23. printf("INTRODUZCA UN NUMERO DEL 1 AL 100 Y DESCUBRA SI ES UN
GANADOR\n");
24.
25. asm{
26. mov ah,02H //Posicionando el cursor
27. mov dh,12

9
28. mov dl,40
29. mov bh,0
30. int 10h
31. }
32. scanf("%d",&dato); //Leyendo el dato del usuario
33.
34. asm{
35. mov ah,02H //Posicionando el cursor
36. mov dh,15
37. mov dl,31
38. mov bh,0
39. int 10h
40. }
41.
42. asm{
43.
44. mov cx,dato //Comparando el dato contra
45. mov ax,pos1 //la primer posicion de memoria
46. cmp ax,cx
47. je ganador
48.
49. mov ax,pos2 //Comparando el dato contra
50. cmp ax,cx //la segundo posicion de memoria
51. je ganador
52.
53. mov ax,pos3 //Comparando el dato contra
54. cmp ax,cx //la tercera posicion de memoria
55. je ganador
56.
57. mov ax,pos4 //Comparando el dato contra
58. cmp ax,cx //la cuarta posicion de memoria
59. je ganador
60.
61. mov ax,pos5 //Comparando el dato contra
62. cmp ax,cx //la quinta posicion de memoria
63. je ganador
64. jmp fin //Salta a fin si no se encuentra
65. } //igualdad en las posiciones de memoria
66.
67. ganador:
68. printf("%s",mensaje1);
69. return 0;
70.
71. fin:
72. printf("%s",mensaje2);
73. return 0;
74. }

Al compilar el código en Borland C se obtuvo lo que muestra la figura 3 para el ingreso de


un dato valido y la figura 4 para el ingreso de un dato valido.

10
Fig. 3: Programa escrito en lenguaje C, con instrucciones de ensamblador para la asignación 3,muestra un
mensaje para un numero invalido.

Fig. 4: Programa escrito en lenguaje C, con instrucciones de ensamblador para la asignación 3, muestra un
mensaje para un numero valido.

11
Asignación 4: Hacer un programa que espere una clave desde consola por ejemplo
“programables”; el programa debe comprobar la clave tecleada con la que se encuentra
en una variable, y si coinciden encender un led verde, si son diferentes encender un led
rojo. Puede utilizar el puerto paralelo. Hágalo con instrucciones de C para escribir en
el puerto, y también hágalo accesando el puerto con lenguaje ensamblador. Comente
diferencias.

Descripción del código: Para este código escrito en C, se hace uso de instrucciones en
ensamblador para validar una clave ingresada y mostrar en pantalla el mensaje de validación.
Código:

1. #include <stdio.h>
2.
3. int main ()
4. {
5. char clave1[12]="programables";
6. char clave[12];
7. printf ("\nBienvenido\n");
8. printf("Introduzca la contrasena\n");
9. scanf("%s",&clave);
10.
11. asm{
12. push dx
13. push cx
14. push bx
15. push ax
16.
17. cld
18. mov si, offset clave1
19. mov di, offset clave
20. mov cx,12
21. repne cmpsb //comparando los caracteres ingresados
22. jcxz wrong //contra la contraseña almacenada
23. jmp right
24.
25. }
26. right:
27. printf("\nLa contrasena ingresada es correcta\n");
28. asm {
29. mov dx,378h
30. mov al,01h //asumiendo que el LED verde esta en el bit o del
puerto
31. out dx,al
32. jmp fin
33. }
34. wrong:
35. printf("\nLa contrasena ingresada es incorrecta\n");
36. asm {
37. mov dx,378h
38. mov al,02h //asumiendo que el LED rojo esta en el bit 1 del
puerto
39. out dx,al
40. jmp fin

12
41. }
42. fin:
43. asm {
44. pop ax
45. pop bx
46. pop cx
47. pop dx
48. }
49. return 0;
50. }

Al compilar el código se obtiene el programa deseado mostrado en la figura 5, donde se


muestra para la clave valida e invalida.

Fig. 5: Programa de validación de clave escrito en C con instrucciones de ensamblador para la asignación 4.

Asignación 5: Investigar cómo se puede trabajar con lenguaje ensamblador en el


sistema operativo Linux, es decir con que programa se puede “ensamblar” y “linkear”
un código de este lenguaje, y cómo usar en este sistema el lenguaje c con lenguaje
ensamblador. Ilustrar un ejemplo sencillo de cada caso.

Existen diferentes herramientas para utilizar lenguaje ensamblador en Linux. Entre ellas se
encuentra el programa ensamblador GAS (AS), en el cual se debe escribir el programa con
sintaxis de AT&T, que tiene las siguientes características:

 Operación fuente, destino

 Se debe indicar el tamaño de los operandos (byte [b], palabra [w], etc.) en cada
opcode.

 Se preceden los registros con un “%” y los literales con el signo “$”.

13
Código ejemplo:

14
CONCLUSIONES

 La combinación de lenguaje ensamblador con lenguaje de alto nivel C, permite la


creación de programas más efectivos ya que comparte la portabilidad y eficiencia de
lenguaje C y la rapidez de ejecución de las instrucciones en ensamblador.

 Se puede utilizar el ensamblado en línea para incrustar instrucciones de lenguaje de


ensamblado directamente en los programas de origen C y C++ sin realizar pasos
adicionales de ensamblado y vínculo.

 El uso de instrucciones de ensamblador en lenguaje C, permite el acceso directo a


periféricos de entrada y salida, por lo que puede facilitar ciertas tareas a la hora de
programar.

 Las aplicaciones que requieren alta velocidad de ejecución deben tener estrictamente
instrucciones de ensamblador ya que ningún otro lenguaje puede acceder
directamente a la memoria de la maquina.

15

You might also like