Skip to content

Commit 1911266

Browse files
U-UC\harvey1U-UC\harvey1
authored andcommitted
added label offsets, fixed some comments
1 parent f51a0ff commit 1911266

5 files changed

Lines changed: 167 additions & 11 deletions

File tree

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ AS4
77

88
AS4 is the low level assembler on written in C99 for the Nibble Knowledge CPU. It is under 700 lines of executable code, and recognises only 12 contructs:
99

10-
## Useage ###
10+
### Useage ###
1111
There are only two invocations of as4:
1212
* ./as4 -b BASE_ADDRESS INPUT OUTPUT
1313
* ./as4 INPUT OUTPUT
@@ -38,8 +38,13 @@ AS4 recognises two inbuilt data types:
3838
Labels are of the format "NAME:". They are used to refer to memory locations without having to memorise or calculate number.
3939
An example of useage would be "number: .data 1 2", which is using the label "number" to point to a data element of 1 nibble in size with the initial value of 2.
4040

41+
Labels when referenced in instructions can be used in two forms:
42+
* INST LABEL - where the instruction INST simply references the memory location pointed to by LABEL
43+
* INST LABEL[OFFSET] - where the instruction INST references the memory location pointed to by LABEL + OFFSET. OFFSET must be a hexidecimal value, optionally preceded by "0x".
44+
An example of usage would be "LOD sum[F]", which loads the memory address pointed to by "sum" plus the offset of "F" (15 in decimal) into the accumulator.
45+
4146
### Comments ###
42-
Comments in AS4 start with a semicolon, ";".
47+
Comments in AS4 start with a semicolon, ";" or an octothorp, "#".
4348

4449
### Example code ###
4550
```nasm

examples/niaomi.asm

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
#a comment
2+
NND lit[F]
3+
NND lit[F]
4+
#Trying a nested Macro
5+
NND lit[F]
6+
ADD lit[1]
7+
#The carry macro
8+
CXA 0
9+
NND lit[1]
10+
NND lit[F]
11+
12+
#simple acc stuff - being exhaustive in my tests
13+
ADD lit[1]
14+
ADD lit[F]
15+
16+
#shifts
17+
STR macro[0]
18+
ADD macro[0]
19+
20+
STR macro[0]
21+
ADD macro[0]
22+
STR macro[0]
23+
CXA 0
24+
NND lit[1]
25+
NND lit[F]
26+
ADD macro[0]
27+
28+
#unary macros! Testing simple first
29+
LOD lit[f]
30+
STR place[0]
31+
32+
#testing that the math works
33+
LOD place[3]
34+
STR elsewhere[a]
35+
LOD place[4]
36+
STR elsewhere[b]
37+
LOD place[5]
38+
STR elsewhere[c]
39+
LOD place[6]
40+
STR elsewhere[d]
41+
LOD place[7]
42+
STR elsewhere[e]
43+
LOD place[8]
44+
STR elsewhere[f]
45+
LOD place[9]
46+
STR elsewhere[10]
47+
LOD place[a]
48+
STR elsewhere[11]
49+
LOD place[b]
50+
STR elsewhere[12]
51+
LOD place[c]
52+
STR elsewhere[13]
53+
LOD place[d]
54+
STR elsewhere[14]
55+
LOD place[e]
56+
STR elsewhere[15]
57+
LOD place[f]
58+
STR elsewhere[16]
59+
LOD place[10]
60+
STR elsewhere[17]
61+
LOD place[11]
62+
STR elsewhere[18]
63+
LOD place[12]
64+
STR elsewhere[19]
65+
66+
#does recursion between acc and unary work?
67+
LOD somewhere[1f]
68+
NND lit[F]
69+
STR place[0]
70+
71+
#more complex recursion - 8-bit negations!
72+
LOD source[0]
73+
NND lit[F]
74+
STR dest[0]
75+
LOD source[1]
76+
NND lit[F]
77+
ADD lit[1]
78+
STR dest[1]
79+
CXA 0
80+
NND lit[1]
81+
NND lit[F]
82+
ADD dest[0]
83+
STR dest[0]
84+
85+
#test addition
86+
LOD lit[0]
87+
ADD num[1]
88+
STR macro[1]
89+
CXA 0
90+
NND lit[1]
91+
NND lit[F]
92+
NND lit[F]
93+
STR macro[0]
94+
LOD macro[1]
95+
ADD num[1]
96+
STR sum[1]
97+
CXA 0
98+
NND lit[1]
99+
NND lit[F]
100+
NND lit[F]
101+
NND macro[0]
102+
ADD num[0]
103+
STR macro[1]
104+
CXA 0
105+
NND lit[1]
106+
NND lit[F]
107+
NND lit[F]
108+
STR macro[0]
109+
LOD macro[1]
110+
ADD num[0]
111+
STR sum[0]
112+
CXA 0
113+
NND lit[1]
114+
NND lit[F]
115+
NND lit[F]
116+
NND macro[0]
117+
118+
macro: .data 50 1
119+
lit: .data 50 1
120+
source: .data 50 1
121+
place: .data 50 1
122+
elsewhere: .data 50 1
123+
somewhere: .data 50 1
124+
dest: .data 50 1
125+
num: .data 50 1
126+
sum: .data 50 1

examples/offsettest.asm

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
LOD beep[0x2]
2+
beep: .data 3 2

src/as4.c

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -132,8 +132,8 @@ int main(int argc, char **argv)
132132
/* Loop until we've gotten every token on this line. */
133133
while(tokens != NULL)
134134
{
135-
/* If we get to a ; on the line, ignore the rest. Allows inline comments */
136-
if(tokens[0] == ';')
135+
/* If we get to a ; or # on the line, ignore the rest. Allows inline comments */
136+
if(tokens[0] == ';' || tokens[0] == '#')
137137
{
138138
break;
139139
}
@@ -268,7 +268,7 @@ int main(int argc, char **argv)
268268
/* A very niche but important instruction. */
269269
else if(!strncmp(tokens, "CXA", 4))
270270
{
271-
/* We only need to understand that it's the halt instruction, we don't care about the rest of the line. */
271+
/* We only need to understand that it's the carry and XOR to accumulator instruction, we don't care about the rest of the line. */
272272
doneline = 1;
273273
/* Add the instruction to the output buffer. */
274274
addinst(outbuf, CXA, NOADDR, &bits, &bytes);
@@ -698,8 +698,8 @@ void addlabel(char *outbuf, label **labels, label **unknownlabels, unsigned long
698698
{
699699
/* If it is, then take stock of both the address it was referenced */
700700
unsigned short int instaddress = (*unknownlabels)[i].addr;
701-
/* And the address the label points to. */
702-
unsigned short int labeladdr = (*labels)[(*numlabels) - 1].addr;
701+
/* And the address the label points to plus the requested offset. */
702+
unsigned short int labeladdr = (*labels)[(*numlabels) - 1].addr + (*unknownlabels)[i].offset;
703703

704704
/* The address it was referenced at is actually the opcode of the instruction, so go up one nibble to point to the address section. */
705705
instaddress++;
@@ -751,7 +751,9 @@ unsigned short int findlabel(label **unknownlabels, label **labels, const char *
751751
unsigned short int address = UNKNOWNADDR;
752752
/* 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. */
753753
unsigned short int tempaddress = address;
754-
754+
/* offset stores the offset in nibbles from the specific label. */
755+
unsigned short int offset = 0;
756+
755757
/* Set errno to 0 so we can check for errors from strtol, which will tell us if the token after the assembly instruction is a number or a label (if it's neither we find out a bit later, not in this function). */
756758
errno = 0;
757759
/* tempaddress is 0 if the labelstr is actually a label and not a value. */
@@ -773,12 +775,28 @@ unsigned short int findlabel(label **unknownlabels, label **labels, const char *
773775
/* Remove any possible whitespace */
774776
for(i = 0; i < strlen(tempstr); i++)
775777
{
776-
if(isspace(tempstr[i]))
778+
if(isspace(tempstr[i]) != 0)
777779
{
778780
tempstr[i] = '\0';
779781
break;
780782
}
781783
}
784+
/* Search for the square brackets to determine label offset */
785+
for(i = 0; i < strlen(tempstr); i++)
786+
{
787+
if(tempstr[i] == '[')
788+
{
789+
offset = strtol(tempstr + ((i + 1) * sizeof(char)), &endptr, 16);
790+
/* Check the offset is in the correct form. If the last character isn't ] for both where we stopped reading the string to find the offest value and where the string ends, then it's wrong. */
791+
/* If both are ], but they're not pointing to the same place (ie: LABEL[HEX_OFFSET]uh oh]) then it's still wrong. */
792+
if((*endptr) != ']' || tempstr[strlen(tempstr) - 1] != ']' || (tempstr + ((strlen(tempstr) - 1) * sizeof(char))) != endptr)
793+
{
794+
fprintf(stderr, "Line %llu: Label offsets must be declared in the form LABEL[HEX_OFFSET].\n", FILELINE);
795+
exit(26);
796+
}
797+
tempstr[i] = '\0';
798+
}
799+
}
782800
/* Check that the pointer to the pointer to the collection of labels is valid .*/
783801
if(labels != NULL)
784802
{
@@ -794,8 +812,8 @@ unsigned short int findlabel(label **unknownlabels, label **labels, const char *
794812
/* Check to see if any names match the one we are looking for. */
795813
if(!strcmp((*labels)[i].str, tempstr))
796814
{
797-
/* If they are, use the address the label points to. */
798-
address = (*labels)[i].addr;
815+
/* If they are, use the address the label points to and add the offset we want. */
816+
address = (*labels)[i].addr + offset;
799817
}
800818
}
801819
}
@@ -823,6 +841,8 @@ unsigned short int findlabel(label **unknownlabels, label **labels, const char *
823841
(*unknownlabels)[0].str = tempstr;
824842
/* and the current location, so the unknown address number can be replaced later. */
825843
(*unknownlabels)[0].addr = (bits/4);
844+
/* and the offset, so we can add it later. */
845+
(*unknownlabels)[0].offset = offset;
826846
/* We have one unknown label now, so record that. */
827847
(*numunknownlabels) = 1;
828848
}
@@ -846,6 +866,8 @@ unsigned short int findlabel(label **unknownlabels, label **labels, const char *
846866
(*unknownlabels)[(*numunknownlabels) - 1].str = tempstr;
847867
/* And where we used it. */
848868
(*unknownlabels)[(*numunknownlabels) - 1].addr = (bits/4);
869+
/* And the offset */
870+
(*unknownlabels)[(*numunknownlabels) - 1].offset = offset;
849871
}
850872
}
851873
}

src/as4.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ typedef struct _label
4242
{
4343
uint16_t addr;
4444
char *str;
45+
uint16_t offset;
4546
} label;
4647

4748
/* Help() prints the help. More useful in large programs */

0 commit comments

Comments
 (0)