Skip to content

Commit b36d6b8

Browse files
committed
added address of, doesn't work yet
1 parent 74bb358 commit b36d6b8

3 files changed

Lines changed: 94 additions & 11 deletions

File tree

src/as4.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -587,7 +587,7 @@ int main(int argc, char **argv)
587587
else if(trimed[strlen(trimed)-1] == ':')
588588
{
589589
/* Add the label to the list of known labels and replace any references to it with it's actual address. */
590-
addlabel(outbuf, &labels, &unknownlabels, &numlabels, numunknownlabels, trimed, bits, baseaddr);
590+
addlabel(outbuf, &labels, &unknownlabels, &numlabels, &numunknownlabels, trimed, bits, baseaddr);
591591
}
592592
else if(inpinf)
593593
{

src/as4.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ void addinst(char *outbuf, uint8_t op, uint16_t addr, unsigned long long *bits,
6666
void adddata(char **outbuf, size_t bufsize, unsigned long long size, long long value, unsigned long long *bits, unsigned long long *bytes);
6767
/* addlabel() adds a label to the collection of labels, to be used by other functions when a label reference is made. */
6868
/* Additionally, if there are outstanding "queries" for a certain label (if the label has been used before it has been declared) it replaces the "unknown address" address in an instruction with the address of the label on declaration */
69-
void addlabel(char *outbuf, label **labels, label **unknownlabels, unsigned long long *numlabels, unsigned long long numunknownlabels, char *labelstr, unsigned long long bits, unsigned short int baseaddr);
69+
void addlabel(char *outbuf, label **labels, label **unknownlabels, unsigned long long *numlabels, unsigned long long *numunknownlabels, char *labelstr, unsigned long long bits, unsigned short int baseaddr);
7070
/* findlabel() determines the memory address that follows the opcode. If the memory address is already a number, returns it */
7171
/* If it is an undeclared label, it adds the label name and the instruction location to the "unknown labels" collection. If the label is declared, it returns it's address */
7272
unsigned short int findlabel(label **unknownlabels, label **labels, char *labelstr, unsigned long long numlabels, unsigned long long *numunknownlabels, unsigned long long bits, uint8_t type);

src/label.c

Lines changed: 92 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
/* addlabel() adds a label to the collection of labels, to be used by other functions when a label reference is made. */
66
/* Additionally, if there are outstanding "queries" for a certain label (if the label has been used before it has been declared) it replaces the "unknown address" address in an instruction with the address of the label on declaration */
7-
void addlabel(char *outbuf, label **labels, label **unknownlabels, unsigned long long *numlabels, unsigned long long numunknownlabels, char *labelstr, unsigned long long bits, unsigned short int baseaddr)
7+
void addlabel(char *outbuf, label **labels, label **unknownlabels, unsigned long long *numlabels, unsigned long long *numunknownlabels, char *labelstr, unsigned long long bits, unsigned short int baseaddr)
88
{
99
/* This is the pointer to the label string, which is used for comparison and assigned to it's element in the collection when we are finished. */
1010
char *tempstr = NULL;
@@ -102,19 +102,34 @@ void addlabel(char *outbuf, label **labels, label **unknownlabels, unsigned long
102102
if((*unknownlabels) != NULL)
103103
{
104104
/* Check every unknown label. */
105-
for(i = 0; i < numunknownlabels; i++)
105+
for(i = 0; i < (*numunknownlabels); i++)
106106
{
107107
/* If the unknown label name exits (otherwise it would be hard to identify it)... */
108108
if((*unknownlabels)[i].str != NULL && strcmp((*unknownlabels)[i].str, ""))
109109
{
110110
/* Check if the name of the unknown label is the same as the label that we just had declared. */
111111
if(!strcmp((*unknownlabels)[i].str, tempstr))
112112
{
113-
/* If it is, then take stock of both the address it was referenced. If a label is referencing a label, we need to move 1 nibble back (as there is no instruction, just 4 nibbles). Cheaper than doing an if below. */
114-
unsigned short int instaddress = (*unknownlabels)[i].addr - (*unknownlabels)[i].type;
115-
/* And the address the label points to plus the requested offset. We need to add one nibble if it is an instruction referencing a nibble as we moved one back above. */
116-
unsigned short int labeladdr = (*labels)[(*numlabels) - 1].addr + (*unknownlabels)[i].offset + (*unknownlabels)[i].type;
117113

114+
/* If it is, then take stock of both the address it was referenced. If a label is referencing a label, we need to move 1 nibble back (as there is no instruction, just 4 nibbles). Cheaper than doing an if below. */
115+
unsigned short int instaddress = (*unknownlabels)[i].addr - ((*unknownlabels)[i].type & 1);
116+
/* And the address the label points to plus the requested offset. We need to add one nibble if it is an instruction referencing a nibble as we moved one back above. */
117+
unsigned short int labeladdr = (*labels)[(*numlabels) - 1].addr + (*unknownlabels)[i].offset + ((*unknownlabels)[i].type & 1);
118+
/* If we are doing an address of operation... */
119+
if(((*unknownlabels)[i].type & 2))
120+
{
121+
/* If N_START is not defined, we don't know how to load just a number. Wait until we do by storing a label to be found later... */
122+
if(N_START == 0xFFFF)
123+
{
124+
char *nstr = calloc(1, 6);
125+
sprintf(nstr, "N_[%X]", ((labeladdr >> (3 - (*unknownlabels)[i].addroffset) & 0xF)));
126+
labeladdr = findlabel(unknownlabels, labels, nstr, (*numlabels), numunknownlabels, bits, ((*unknownlabels)[i].type) & 1);
127+
}
128+
else
129+
{
130+
labeladdr = ((labeladdr >> (3 - (*unknownlabels)[i].addroffset) & 0xF)) + N_START;
131+
}
132+
}
118133
/* The address it was referenced at is actually the opcode of the instruction, so go up one nibble to point to the address section. */
119134
instaddress++;
120135
/* Since the instaddress is actually what nibble is being addressed, we correctly address a byte every 2 nibbles. */
@@ -166,7 +181,8 @@ unsigned short int findlabel(label **unknownlabels, label **labels, char *labels
166181
/* tempaddress is what is assigned to the return value of strtol. We use this value if we find that the token after the assembly instruction is actually a number. */
167182
unsigned short int tempaddress = address;
168183
/* offset stores the offset in nibbles from the specific label. */
169-
unsigned short int offset = 0;
184+
unsigned short int offset = 0;
185+
unsigned short int addroffset = 0;
170186

171187
if(type > 1)
172188
{
@@ -198,9 +214,76 @@ unsigned short int findlabel(label **unknownlabels, label **labels, char *labels
198214
break;
199215
}
200216
tempstr[i] = labelstr[i];
201-
}
202-
217+
}
203218
tempstr[i] = '\0';
219+
220+
/* Check to see if this is an address of operation */
221+
if(tempstr[0] == '&')
222+
{
223+
/* The formatting for this operation is very specific and we can find failures in multiple levels of parsing */
224+
/* Have one value we set */
225+
unsigned char formatcorrect = 0;
226+
227+
/* The second character must be a ( */
228+
if(tempstr[1] == '(')
229+
{
230+
/* Go until we find the ), which encompasses the label we are taking the address of */
231+
for(i = 2; i < strlen(tempstr); i++)
232+
{
233+
if(tempstr[i] == ')')
234+
{
235+
/* If the ) is right beside the end of the string, it means that it is in the form &(LABEL). This is ok */
236+
if(tempstr[i+1] == '\0')
237+
{
238+
formatcorrect = 1;
239+
}
240+
/* If the ) is right beside [, the string should be in the form &(LABEL)[ADDRESS_OFFSET] */
241+
else if(tempstr[i+1] == '[')
242+
{
243+
/* Try to convert the offset */
244+
addroffset = estrtol(tempstr + ((i + 2) * sizeof(char)), &endptr, NSTDHEX);
245+
/* If the value is valid (there is a convertable number)... */
246+
if(tempstr != endptr)
247+
{
248+
/* And if the first invalid character was ] and then the string ends, this is correctly in the form &(LABEL)[ADDRESS_OFFSET] */
249+
if(endptr[0] == ']' && endptr[1] == '\0')
250+
{
251+
/* However, the offset must be between 0 and 3 as addresses are 4 nibbles. */
252+
if(addroffset > 3 || addroffset < 0)
253+
{
254+
fprintf(stderr, "Line %llu: The offset of an address of operation must be between 0 and 4.\n", FILELINE);
255+
exit(51);
256+
}
257+
formatcorrect = 1;
258+
}
259+
}
260+
}
261+
}
262+
if(formatcorrect)
263+
{
264+
/* Bitwise or ADDROF (which is 2) to the type. We can use this in addlabel to know if we are doing an address of operation. */
265+
type |= ADDROF;
266+
/* Strip the address of parts from this string so we can use the rest of the function to correctly fill the string, address and offset parts of the unknownlabel structure. */
267+
for(i = 2; i < strlen(tempstr); i++)
268+
{
269+
if(tempstr[i] == ')')
270+
{
271+
tempstr[i-2] = '\0';
272+
break;
273+
}
274+
tempstr[i-2] = tempstr[i];
275+
}
276+
}
277+
}
278+
}
279+
/* If the string has not passed all the trials, punish the user. */
280+
if(formatcorrect = 0)
281+
{
282+
fprintf(stderr, "Line %llu: Format of an address of operation must be &(LABEL[OFFSET])[ADDRESS_OFFSET].\n", FILELINE);
283+
exit(52);
284+
}
285+
}
286+
204287
/* Search for the square brackets to determine label offset */
205288
for(i = 0; i < strlen(tempstr); i++)
206289
{

0 commit comments

Comments
 (0)