Arquitectura de Computadoras
Práctica Adicional Ensamblador
Equipo 11
Luis Manuel Rodríguez Ramírez,
Luis Fernando Maciel García
26 de Marzo de 2014
Introducción
¿Qué es el ensamblador?
El ensamblador hace referencia a un tipo de programa informático encargado de traducir un fichero fuente escrito en lenguaje ensamblador, a un fichero objeto que contiene código máquina, ejecutable directamente por el procesador. Cada instrucción representa exactamente una instrucción de la máquina.
Los compiladores son programas que hacen conversiones similares a los ensambladores pero sirven para lenguajes de programación de alto nivel, un ensamblador es más simple que un compilador, en un lenguaje de alto nivel se pueden requerir muchas instrucciones de máquina y en lenguaje ensamblador cada instrucción representa una sola instrucción de máquina. Cada tipo de CPU tiene su propio lenguaje de máquina, también tiene su propio lenguaje ensamblador. Trasladar programas entre arquitecturas de computador diferentes es algo complicado.
Los objetivos de ésta práctica son crear un ensamblador sencillo, que va a crear un archivo de texto con código máquina el cual puede servir para ser el archivo de entrada para el simulador de una computadora. Al recibir una instrucción le vamos a asignar un código de operación y se generará el código de salida. La importancia de ésta práctica es conocer como trabaja un ensamblador y de ver cómo se genera el código máquina a través de instrucciones en lenguaje ensamblador.
Desarrollo de la práctica
En la práctica simulamos el trabajo de un ensamblador, la realizamos en lenguaje C++, lo que necesitamos fue lo siguiente:
•
Computadora•
Compilador g++El programa va a interpretar un archivo de entrada en lenguaje ensamblador y va a generar la salida de lenguaje máquina. Cada linea del programa en ensamblador va a tener la estructura siguiente.
Dirección_de_memoria Operación Operando y para guardar datos en memoria vamos a tener la siguiente sintaxis
Dirección_de_memoria Operando
El archivo de entrada fue abierto a través de un puntero tipo FILE y separado por renglones con la función fgets() y asignado a una variable tipo char para sacar la instrucción de cada renglón. Al leer con fgets obtuvimos cada renglón del archivo de entrada y lo asignamos a las variables con las que vamos a trabajar de la forma siguiente:
char renglon[100];
unsigned int indice, operando_s=0x000; char cadena[100];
char cop_s[10];
FILE *entrada= fopen(“entrada.txt”,”r”); while(!feof(entrada)){
fgets(renglon,99,entrada);
scanf(cadena,"%x %s %x",&indice,cop_s,&operando_s); }
La codificación a lenguaje máquina fue simple debido a que solo le revisamos la operación que es y le asignamos su código de operación. La instrucción codificada queda junto con el operando de la siguiente forma.
Código de Operación
Operando
En la siguiente tabla tenemos los códigos de operación correspondientes a la instrucción que se le asignaron al ensamblarlo.
Código de
Operación
Instrucción
0 h
LOAD
2 h
ADD
3 h
ADC
4 h
SUB
5 h
OR
6 h
AND
7 h
XOR
8 h
SHL
9 h
SHR
A h
BRA
B h
BRZ
C h
BRC
D h
BRO
E h
LDI
F h
STOP
Para asignarle a cada instrucción su código de operación lo hicimos comparando la cadena que contenía la instrucción con la función strcmp, como el ejemplo siguiente:
En el renglón leemos la instrucción y entramos a condicionantes para asignar el código de operación correspondiente. El renglón que leemos tiene 001 ADD 010, entonces la instrucción va a entrar a la condicionante que contenga la cadena “ADD”. Al encontrar la instrucción le sumamos el código de operación con corrimiento a la izquierda de 12 bits al operando para obtener ya la instrucción codificada y la vamos a guardar en un arreglo simulando la memoria.
if(!strcasecmp(cop_s,"ADD")){
memoria[indice]=0x2000+ Operando; }
Una vez que se leyeron todos los renglones pusimos una verificación para que la instrucción LDI la cual su funcionamiento es cargar una constante en la localidad siguiente de memoria así que revisamos que no se toque esa localidad siguiente. Ya que comprobamos que se respetó la siguiente localidad de memoria de la instrucción LDI continuamos con la generación del código máquina. El código de salida se va a limitar a aquellas localidades de memoria que tengan alguna instrucción o algún dato que tengamos que guardar en la memoria. Para generar el archivo de salida con el código máquina hicimos lo siguiente:
if(memoria[i]!=0){ fprintf(entrada,"%03x %04x\n",i,memoria[i]); } }
Resultados
Primero compilamos el código en C++ con g++
y ejecutamos
El archivo con el que probamos tenía el código en ensamblador 000 load 010 001 add 011 002 bro 005 003 store 014 004 bra 006 005 store 015 006 stop 010 4AAA 011 5CDE
El archivo en código máquina obtenido es el siguiente 000 0010 001 2011 002 d005 003 1014 004 a006 005 1015 006 f000 010 4aaa 011 5cde
Conclusiones
Conocer como trabaja un ensamblador es importante ya que nos da una visión más amplia de cómo se traducen de lenguaje ensamblador a lenguaje máquina, en la práctica se buscó realizar el ensamblador a partir de un archivo de entrada. El lenguaje máquina es muy difícil de programar ya que las instrucciones son codificadas numéricamente y se volvería tedioso para programar. Los objetivos de la práctica fueron completados en su totalidad. A futuro se puede complementar el ensamblador para que se ejecuten las instrucciones que metemos en el archivo de entrada y que podamos ver que pasos se van siguiendo. El ensamblador que realizamos en la práctica es muy básico ya que no se entra en mucho detalle para todas las instrucciones, es de mucha ayuda para comprender el código máquina debido a que todos los lenguajes de programación llegan a generar su respectivo código máquina en su compilación.
Referencias
Paul A. Carter . “Lenguaje Ensamblador para PC ”. Consultado en linea en
http://collection.openlibra.com.s3.amazonaws.com/pdf/pcasm-book-spanish.pdf?
AWSAccessKeyId=AKIAIGY5Y2YOT7GYM5UQ&Signature=ypsUCMdU4pRFSDhVKvfeVulh2gU %3D&Expires=1395977911