-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathassembler.c
213 lines (153 loc) · 4.73 KB
/
assembler.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
/******************************************************************************/
/* Assembler project for course 20465 */
/* Programmed by : Itay Parsiado (ID:062862495) & Shai Aharoni (ID:025332990) */
/******************************************************************************/
#define _GNU_SOURCE /*For using strdup without compiler warnings*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "parser.h"
#include "firstpass.h"
#include "secondpass.h"
#include "assembler.h"
#include "output.h"
unsigned int IC; /* The instruction counter */
unsigned int DC; /* The data counter */
#define NO_ASSEMBER_ARGUMENTS_ERROR "No assembly files supplied. Usage is: Assembler [file1] [file2] ...\n"
#define FILE_NAME_NOT_VALID "Assembly file:%s is not valid\n"
#define FIRST_PASS_FAILED "Executing first pass on file:%s failed.\n"
#define SECOND_PASS_FAILED "Executing second pass on file:%s failed.\n"
#define OB_FILE_CREATION_FAILED "Creating .ob file for assembly file:%s, failed\n"
#define ENT_FILE_CREATION_FAILED "Creating .ent file for assembly file:%s, failed\n"
#define EXT_FILE_CREATION_FAILED "Creating .ext file for assembly file:%s, failed\n"
#define ASSEMBLER_EXECUTION_FAILED 1 /*General failure exit code */
char *DataMemory[DATA_MEMORY_SIZE];
char *InstructionMemory[INSTRUCTION_MEMORY_SIZE+1]; /*Last char is for the linker*/
void insertIntToDataMemory(int value);
int main(int argc, char *argv[])
{
FILE *file;
char *assemblyFileName, *fileNameWithoutExtension;
int i, fileCreateResult;
if(argc < 2) fprintf(stderr, NO_ASSEMBER_ARGUMENTS_ERROR);
for(i = 1; i<argc ; i++) /*Iterate over all the assembly files */
{
fileNameWithoutExtension = strdup(argv[i]); /*We need to keep the name for the output files*/
assemblyFileName = (char *)malloc(strlen(fileNameWithoutExtension) + strlen(ASSEMBLY_FILE_EXT) + 1); /*Allocate memory for the full assembly file name*/
if(assemblyFileName == NULL) /*Memory could not be allocated*/
{
exit(ASSEMBLER_EXECUTION_FAILED);
}
/*Build the full assembly file name*/
assemblyFileName = strdup(argv[i]);
strcat(assemblyFileName, ASSEMBLY_FILE_EXT);
if((file = fopen(assemblyFileName, "r")) != NULL)
{
if(!executeFirstPass(file))
{
fprintf(stderr, FIRST_PASS_FAILED, assemblyFileName);
continue;
}
if(!executeSecondPass())
{
fprintf(stderr, SECOND_PASS_FAILED, assemblyFileName);
continue;
}
fileCreateResult = writeObjFile(fileNameWithoutExtension, InstructionMemory, DataMemory);
if(fileCreateResult == FILE_COULD_NOT_BE_CREATED)
{
fprintf(stderr, OB_FILE_CREATION_FAILED, assemblyFileName);
}
fileCreateResult = writeExtFile(fileNameWithoutExtension);
if(fileCreateResult == FILE_COULD_NOT_BE_CREATED)
{
fprintf(stderr, EXT_FILE_CREATION_FAILED, assemblyFileName);
}
fileCreateResult = writeEntFile(fileNameWithoutExtension);
if(fileCreateResult == FILE_COULD_NOT_BE_CREATED)
{
fprintf(stderr, ENT_FILE_CREATION_FAILED, assemblyFileName);
}
} else
{
fprintf(stderr, FILE_NAME_NOT_VALID, assemblyFileName);
exit(ASSEMBLER_EXECUTION_FAILED);
}
free(assemblyFileName);
}
return 0;
}
/* Inserts a data or string to the data memory image. */
/* The function assumes that the line contains a data guidance command. */
void insertDataToMemory(char *line)
{
StatementType type;
char *data;
int i;
type = getStatementType(line);
if(type == DATAGUIDANCE)
{
data = extractGuidanceData(line);
data = extractFirstGuidanceData(data);
while(data != NULL)
{
insertIntToDataMemory(atoi(data));
DC++;
data = extractNextGuidanceData();
}
} else /*String guidance */
{
data = extractGuidanceString(line);
for(i=0; i<strlen(data); i++)
{
insertIntToDataMemory(data[i]);
DC++;
}
/* Add "zero" word */
insertIntToDataMemory(0);
DC++;
}
}
void insertInstructionToMemory(char *word, char *linkerChar)
{
if(linkerChar != NULL)
{
InstructionMemory[IC] = strcat(word, linkerChar);
} else
{
InstructionMemory[IC] = word;
}
IC++;
}
/* Inserts an integer value to the data memory*/
void insertIntToDataMemory(int value)
{
char *word;
word = convertBase10toBase2(value);
DataMemory[DC] = word;
}
void addAssemblerError(const char *errorMessage, int lineNumber)
{
fprintf(stderr, "Error at line %d:%s\n",lineNumber, errorMessage );
}
unsigned int getInstructionCounter()
{
return IC;
}
unsigned int getDataCounter()
{
return DC;
}
void resetAssemblyCounters()
{
IC = 0;
DC = 0;
}
char *getInstructionMemoryWord(unsigned int index)
{
return InstructionMemory[index];
}
void setInstructionMemoryWord(unsigned int index, char *value, char *linkerChar)
{
InstructionMemory[index] = strcat(value, linkerChar);
}