Un poco de teoría
Primero conoceremos que son los ensambladores :3Ensambladores
- Ensambladores de una pasada
- Con salida en Binario ( Conocidos también como load and go )
- Con salida simbólica-binaria
- Ensambladores de dos pasadas
Ensamblador de dos pasadas
En este pequeño tutorial se realizará un ensamblador de dos pasadas.Primer paso
En el primer paso la prioridad es obtener las tablasPasos a realizar durante el primer paso
- Tratamiento de etiquetas( instrucciones ).
- Buscar en tabla de símbolos (si no está, pasar al siguiente paso).
- Insertar en tabla de símbolos.
- Tratamiento de código de operación.
- Buscar en tabla de código de operación y actualizar campo de dirección.
- Escribir código de operación.
- Buscar en tabla de pseudo- instrucciones y hacer el tratamiento de la pseudo-instrucción.
- Análisis del operando (en caso de la creación de un código intermedio).
- Almacenar en tabla de símbolos.
- Buscar en tabla de símbolos.
- Sustituir por dirección en tabla de símbolos.
Segundo paso
Sus objetivos son obtener el programa en simbólico y binario, crear las tablas para el linker ( enlazador o ligador ), y localizar las variables ( puede incluir un dump ).Pasos a realizar durante el segundo paso
- Tratamiento del código de operación
- Buscar en tabla de código de operación.
- Actualizar contador de direcciones.
- Buscar tabla de pseudo-instrucción (si es símbolo).
- Tratamiento del operando.
- Buscar en tabla de símbolo (si es símbolo).
- Obtener valor
- Escribir código objeto
Tablas a usar
( pendiente aunque ya estén en el código :P )
Codificando
Borrar variables anteriores y limpiar área de impresión
%% Universidad Autónoma de Tlaxcala
% Blanca Leticia Milácatl López
%%
%
%
%% Inicialización
clear, clc
%% TABLAS
%Para poder realizar la conversión se proveen las siguientes tablas
%% tabla de direccion simbolica de los simbolos de direccion
tabla_direccion_simbolica_simbolos_direccion = [];
codigo_de_caracteres_hexadecimales_letras = ['A'; 'M'; 'Y';
' '; 'B'; 'N'; 'Z'; '('; 'C'; 'O';
'0'; ')'; 'D'; 'P'; '1'; '*'; 'E';
'Q'; '2'; '+'; 'F'; 'R'; '3'; ';';
'G'; 'S'; '4'; '-'; 'H'; 'T'; '5';
'.'; 'I'; 'U'; '6'; '/'; 'J'; 'V';
'7'; '='; 'K'; 'W'; '8'; 'L';
'X'; '9']; %caracter y código
diagn = ['\n'];
codigo_de_caracteres_hexadecimales_hexa = ['41'; '4D'; '59';
'20'; '42'; '4E'; '5A'; '28'; '43'; '4F';
'30'; '29'; '44'; '50'; '31'; '2A'; '45';
'51'; '32'; '2B'; '46'; '52'; '33'; '2C';
'47'; '53'; '34'; '2D'; '48'; '54'; '35';
'2E'; '49'; '55'; '36'; '2F'; '4A'; '56';
'37'; '3D'; '4B'; '57'; '38'; '4C';
'58'; '39']; %caracter y código
diagn_num = ['OD'];
%% tabla del conjunto de instrucciones a hexa
conjunto_instrucciones=['AND',% 0 or 8 AND M to AC
'ADD',% 1 or 9 Add M to AC, carry to E
'LDA',% 2 or A Load AC from M
'STA',% 3 or B Store AC in M
'BUN',% 4 or C Branch unconditionally to m
'BSA',% 5 or D Save return address in m and branch to m+1
'ISZ',% 6 or E Increment M and skip if zero
'CLA',% 7800 Clear AC
'CLE',% 7400 Clear E
'CMA',% 7200 Complement AC
'CME',% 7100 Complement E
'CIR',% 7080 Circulate right E and AC
'CIL',% 7040 Circulate left E and AC
'INC',% 7020 Increment AC, carry to E
'SPA',% 7010 Skip if AC is positive
'SNA',% 7008 Skip if AC is negative
'SZA',% 7004 Skip if AC is zero
'SZE',% 7002 Skip if E is zero
'HLT',% 7001 Halt computer
'INP',% F800 Input information and clear flag
'OUT',% F400 Output information and clear flag
'SKI',% F200 Skip if input flag is on
'SKO',% F100 Skip if output flag is on
'ION',% F080 Turn interrupt on
'IOF'];%F040 Turn interrupt off
hexa_instrucciones ={'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7800',
'7400',
'7200',
'7100',
'7080',
'7040',
'7020',
'7010',
'7008',
'7004',
'7002',
'7001',
'F800',
'F400',
'F200',
'F100',
'F080',
'F040'
};
%% Leer el código fuente
fid = fopen('miarchivo.txt','r');
cadenas = fread(fid, '*char')';
fclose(fid);
%% Separar parte de fuconamiento y área de datos
%cadenas= textscan(fid,'%s')
%cadenas=cell2struct(textread('miarchivo.txt','%s', 'whitespace', ''),,1)
[f,c] = size(cadenas);
indice = findstr(cadenas,'HLT')
primeraparte = cadenas(1:indice+3)
segundaparte = cadenas(indice+5:c)
%% Obtener la posicion inicial en memoria
[ppf,ppc] = size(segundaparte);
pos_inicial = findstr(primeraparte,'ORG')+3;
cadnasdepuesorg=cadenas(pos_inicial-3:c)
inicio_memoria = primeraparte(pos_inicial:ppc);
inicio_memoria=textscan(inicio_memoria,'%d');
inicio_memoria=inicio_memoria{1};
%% obtiene la dirección de cada línea a partir de la posición inicial en
%% memoria
programasinorgend = cadnasdepuesorg(1:findstr(cadnasdepuesorg,'END')-1) %guardamos eliminando org y ends
lineas = strread(programasinorgend,'%s','delimiter',sprintf('\n'));
lineas = string(char(lineas))
[num_lineas,c]=size(lineas);
direcciones = [inicio_memoria:inicio_memoria+num_lineas]; %se necesitará pasar a hexadecimal despues
%% imprimir el programa ya con direcciones de referencia
for i=1:num_lineas-1
%disp(direcciones(i))
disp(sprintf('%s\t%s',num2str(direcciones(i)),lineas(i+1,:)));
end
% obtiene las líneas
programa_por_lineas = strread(cadenas,'%s','delimiter',sprintf('\n'));
for i=1:num_lineas-1
%programa_por_lineas(i,:)=sprintf('%s\t%s',num2str(direcciones(i)),lineas(i+1,:));
programa_por_lineas(i,:)={sprintf('%s\t%s',num2str(direcciones(i)),lineas(i+1,:))};
end
% compostura para que salga bien
n_programa_por_lineas=[cellstr(programa_por_lineas(1:num_lineas-1));cellstr(programa_por_lineas(num_lineas+1))];
disp('Programa con direcciones de memoria')
disp(n_programa_por_lineas)
%% Preparar la TABLA DE SIMBOLOS DE DIRECCION
[spf,spc] = size(segundaparte);
parte_tabla_simbolos = segundaparte(1:findstr(segundaparte,'END')-1)
parte_tabla_simbolos = strread(parte_tabla_simbolos,'%s','delimiter',sprintf('\n'));
[tsf,tsc]=size(parte_tabla_simbolos); %tamaño de la parte donde se saca la tabla de símbolos
tabla_simbolos=[];
valor_tabla_simbolos=[];
%ooops pequeño error, usar el k tiene las direcciones si se puede y guardar
%dirección y símbolo
for num_lineas_felices=1:1:tsf
%valor_tabla_simbolos(num_lineas_felices)=
[simbolo,resto] = strtok(parte_tabla_simbolos(num_lineas_felices,:));
tabla_simbolos=[tabla_simbolos, simbolo];
disp( simbolo );
[tipo_dato,resto1]=strtok(resto(1,:));
%pendiente:
%tratar aquí x para saber el tipo de dato, si es DEC usar str2num
%luego num2hexpara guardar su valor hexadecimal
%si es HEX ya está en hexadecimal
switch upper(char(tipo_dato))
case 'DEC'
num = str2num(char(resto1));
hexad = num2hex(single(num));
resto1 = hexad;
case 'HEX'
num = hex2dec(char(resto1));
hexad = num2hex(single(num));
resto1 = hexad;
otherwise
error('tipo de datos no reconocido')
end
valor_tabla_simbolos=[valor_tabla_simbolos;resto1];
disp(resto1);
end
%%valor_tabla_simbolos=char(parte_tabla_simbolos) %no sé para que había
%%puesto esto XD
%simbolos_y_sus_valores(i,:)=strrep(parte_tabla_simbolos(i,:), tabla_simbolos(i,:), valor_tabla_simbolos(i,:)); % pendiente remplazar los
%valores en el programa con las direcciones
%obtener de direcciones los ´ltimos índces hasta el tamaño de simbolos
[datosf, datosc]=size(char(valor_tabla_simbolos));
[programaf,programac]=size(n_programa_por_lineas);
dir_inicio_remplazo = programaf-datosf;
programa_con_direcciones_muy_felices = n_programa_por_lineas; % pendiente cambiar tamañoi
instrucciones=[];
direcciones_instr = [];
for ind = programaf:-1:dir_inicio_remplazo+1
cad=char(tabla_simbolos(1,programaf+1-ind));
instr=cad(1:3)
instrucciones=[instrucciones;instr];
%programaf-ind
direcciones_instr=[direcciones_instr;num2str( direcciones(dir_inicio_remplazo-1+(programaf-ind)) )];
% valor_tabla_simbolos(programaf+1-ind,:)
programa_con_direcciones_muy_felices(dir_inicio_remplazo+(programaf-ind)) = cellstr(sprintf('%s\t%s %s',num2str( direcciones(dir_inicio_remplazo-1+(programaf-ind)) ),instr,valor_tabla_simbolos(programaf+1-ind,:)))
end
copia_tabla_simbolos = tabla_simbolos;
%for i=1:dir_inicio_remplazo
% strrep(copia_tabla_simbolos(i)
%end
%% encontrar los mnemónicos en las tablas y reemplazar
Notas
La variable fid es por file identifier o identificador de archivo, no confundir con find.Este código es a fuerza bruta, no está optimizado.
He estado ayudando en este proyecto, más avances pronto. No olviden comentar.