Sei sulla pagina 1di 8

Ex 6:

Implement single pass assembler.

Aim:
To implement single pass assembler.

Algorithm:
1. Read input file “opcode.txt” and copy its content into optab structure in respective
field.

2. Read line by line from “input.txt” (assembly program). Assume each line contains 3
fields, namely “label”, “opcode” and “operand” respectively.

3. Do the following steps.


3.1) if opcode == “START”, initialize LOC with operand. Treat label as program
name.

3.2) if opcode == “END”, this marks end file. Stop reading input file. Jump to step 5.

3.3) if opcode == “WORD”, then


a) insert label & operand into symbol table in corresponding field
(name & value).
b) copy LOC into structure member output.loc & operand into
structure member output.operand. Initialize “***” into
output.opcode since this instruction does not produce any opcode.
c) Increment LOC by 3.
3.4) if opcode == “RESW”, then
a) insert label into symbol.name. Copy LOC value into symbol.value.
b) increment LOC by LOC + operand * 3.

3.5) if opcode == “BYTE”, then


a) insert label into symbol.name. Copy LOC value into symbol.value.
b) copy LOC into structure member output.loc & operand into
structure member output.operand. Initialize “***” into
output.opcode since this instruction does not produce any opcode
c) increment LOC by strlen(operand)-3 if operand is character string.
d) increment LOC by 1 if operand is hexa decimal value.

3.6) if opcode == “RESB”, then


a) insert label into symbol.name. Copy LOC value into symbol.value.
b) increment LOC by LOC + operand.

3.7) For any other opcode value, treat them as machine instruction. Do the following
steps.
a) Operand:Suppose operand is present in symbol structure, add the
operand and mark it by the value “-1”. Save the operand field
address in symbol.ref. This indicates forward ref on label.
b) label: Check the label is present in symbol table are not.
i) If present, put LOC value into symbol.value for
corresponding symbol. Insert symbol.value into
output.operand. Index in output structure is referred by
symbol.ref value.
j) If not present, insert symbol & LOC into symbol.name and
symbol.value fields.
c) opcode: find opcode value for corresponding machine instruction.
Update into
output.opcode. Increment LOC by LOC + 3. (since 3 byte
instruction).

4. Repeat step 3 until reach end of input file.


5. Now the translated object code is present in output structure. Print object code with
header, text and end record format.

CODE :

#include<stdio.h>
#include<string.h>
struct optab
{
char inst[8];
char opc[4];
}op[10];
struct symbol
{
char name[10];
int val;
int ref;
}sym[10];
struct output
{
char type;
int loc;
char opcode[10];
char operand[8];
}out[50];
int n,k,m,l;
char r[10];
void conv(int x)
{
int i,z=0,j;
char s[10];
j=0;
while(x>0)
{
i=x%10;
s[z]=i+48;
x=x/10;
z++;
}
s[z]='\0';
for(i=strlen(s)-1;i>=0;i--)
{
r[j]=s[i];
j++;
}
r[j]='\0';
}
int check_sym(char x[10])
{
int i;
for(i=0;i<n;i++)
if(strcmp(x,sym[i].name)==-0)
return i;
return -1;
}
int check_op(char x[10])
{
int i;
for(i=0;i<l;i++)
{
if(strcmp(op[i].inst,x)==0)
return i;
}
return -1;
}
void store()
{
int i;
FILE *f;
i=0;
f=fopen("onepassopcode.txt","r");
while(!feof(f))
{
fscanf(f,"%s\t%s\n",op[i].inst,op[i].opc);
i++;
}
fclose(f);
l=i;
}
int sloc,eloc;
char sname[10];
void outs()
{
int i,j;
char vals[10];
FILE *f;
n=0;
m=0;
char label[10],operand[10],opcode[10];
int loc;
f=fopen("onepassinput.txt","r");
while(!feof(f))
{
fscanf(f,"%s\t%s\t%s\n",label,opcode,operand);
if(strcmp(opcode,"START")==0)
{
loc=atoi(operand);
sloc=loc;
strcpy(sname,label);
}
else if(strcmp(opcode,"END")==0)
{
eloc=loc-3;
break;
}
else if(strcmp(opcode,"WORD")==0)
{
strcpy(sym[n].name,label);
sym[n].val=loc;
n++;
out[m].loc=loc;
strcpy(out[m].operand,operand);
strcpy(out[m].opcode,"***");
m++;
loc+=3;
}
else if(strcmp(opcode,"RESW")==0)
{
strcpy(sym[n].name,label);
sym[n].val=loc;
loc+=(atoi(operand)*3);
n++;
}
else if(strcmp(opcode,"RESB")==0)
{
strcpy(sym[n].name,label);
sym[n].val=loc;
loc+=atoi(operand);
n++;
}
else if(strcmp(opcode,"BYTE")==0)
{
strcpy(sym[n].name,label);
sym[n].val=loc;
n++;
if(operand[1]==39)
{
i=2;j=0;
while(operand[i]!=39)
{
vals[j]=operand[i];
i++;
j++;
}
vals[j]='\0';
}
strcpy(out[m].operand,vals);
strcpy(out[m].opcode,"***");
out[m].loc=loc;
if(operand[0]=='C')
loc+=(strlen(operand)-3);
if(operand[0]=='X')
loc+=1;
m++;
}
else
{
i=check_sym(operand);
if(i==-1)
{
sym[n].val=-1;
strcpy(sym[n].name,operand);
sym[n].ref=m;
n++;
}
else
strcpy(out[m].operand,sym[i].name);
if(strcmp(label,"NULL")!=0)
{
i=check_sym(label);
if(i==-1)
{
strcpy(sym[n].name,label);
sym[n].val=loc;
n++;
}
else
{
sym[i].val=loc;
conv(loc);
strcpy(out[sym[i].ref].operand,r);
}
}
j=check_op(opcode);
strcpy(out[m].opcode,op[j].opc);
m++;
loc+=3;
}
}
}
void output()
{
FILE *f;
int i,j;
char vals[10];
for(i=0;i<m;i++)
{
j=check_sym(out[i].operand);
if(j!=-1)
out[i].loc=sym[j].val;
if(out[i].loc==0)
out[i].loc=atoi(out[i].operand);
}
f=fopen("onepassoutput.txt","w");
fprintf(f,"H\t%s\t%d\t%d",sname,sloc,(eloc-sloc));
for(i=0;i<m;i++)
{
if(strcmp(out[i].opcode,"***")==0)
strcpy(vals,out[i].operand);
else
{
strcpy(vals,out[i].opcode);
conv(out[i].loc);
strcat(vals,r);
}
if((i%6)==0)
fprintf(f,"\nT");
fprintf(f,"\t%s",vals);
}
fprintf(f,"\nE\t%d",sloc);
fclose(f);
}

int main()
{
int i;
store();
outs();
output();
}

Sample input/output:

Input.txt

READ START 1000


INPUT BYTE C'F1'
MAXLEN WORD 1024
BUFFER RESB 4
LENGTH RESW 2
ZERO WORD 0
NULL LDX ZERO
NULL LDA ZERO
NULL TD INPUT
NULL JEQ RLOOP
NULL RD INPUT
NULL COMP ZERO
NULL JEQ EXIT
RLOOP STCH BUFFER
NULL TIX MAXLEN
NULL JLT RLOOP
EXIT STX LENGTH
NULL END NULL

Opcode.txt

LDA 00
LDX 04
TD E0
JEQ 30
RD D8
COMP 28
STCH 54
TIX 2C
JLT 38
STX 10

Output.txt:

H READ 1000 48
T F1 1024 0 041015 001015 E01000
T 301039 D81000 281015 301048 541005 2C1002
T 381039 101009
E 1000

RESULT:
Thus the single pass assembler has been implemented in c language.

Potrebbero piacerti anche