A couple of posts ago I started talking about the IAS architecture, mentioning that given its simplicity you can program it directly in machine code. That being said, any program slightly more complex will be painful to write in machine code. For instance, image how boring it would be if you needed to declare an array with 5000 elements, all initialized to the value 10.
That’s where assemblers come into play. Apart from translating from assembly language to machine code they also have directives you can use to make your job as a programmer much easier. Below you’ll find an assembler I created for the IAS architecture.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
/* data structures to hold the labels and .set constants */
//holds the name
char labelTable[500][1000];
//holds the value and, in case of memory, the alignment
int addressTable[500][2];
//holds size of the stack
int tablePosition = 0;
/* function that searchs and returns the value
of a label/.set, aborts if it can't find one */
int labelToNumber(char *label, int line){
int i;
for(i=0;i<tablePosition;i++){
if(!strcmp(label,labelTable[i])){
return addressTable[i][0];
}
}
printf("--Valor de endereco ou rotulo invalido, linha %dn",line);
abort();
return 0;
}
/* function that validates a number. Return 0 if non valid, 1 if decimal, 2 if hex, 3 if binary, 4 if octal */
int validateNumber(char *number){
int i;
int len = strlen(number);
/* checks strings with up to 2 chars, which can only represent decimal numbers */
if(len==0)
return 0;
else if(len==1){
if(number[0]>47&&number[0]<58)
return 1;
else
return 0;
}
else if(len==2){
if((number[0]>47&&number[0]<58)&&(number[1]>47&&number[1]<58))
return 1;
else
return 0;
}
/* string has >3 chars */
else{
/* checks if number is hex */
if(number[0]=='0'&&number[1]=='X'){
for(i=2;i<len;i++)
if((number[i]<48||number[i]>57)&&(number[i]<65||number[i]>70))
return 0;
return 2;
}
/* checks if number is binary */
else if(number[0]=='0'&&number[1]=='B'){
for(i=2;i<len;i++)
if(number[i]<48||number[i]>49)
return 0;
return 3;
}
/* checks if number is octal */
else if(number[0]=='0'&&number[1]=='O'){
for(i=2;i<len;i++)
if(number[i]<48||number[i]>55)
return 0;
return 4;
}
/* number is decimal */
else{
for(i=2;i<len;i++)
if(number[i]<48||number[i]>57)
return 0;
return 1;
}
}
}
/* function that reads a memory address or number as a string and return its converted decimal form, as an int */
int convertAddress(char *address, int lineCounter){
int result;
unsigned int value;
int len,i;
int base = 1;
char newnumber[1000];
if((result = validateNumber(address))){
/* number is valid and decimal */
if(result==1){
return atoi(address);
}
/* number is valid and binary */
else if(result==3){
value = 0;
len = strlen(address);
for (i=len-1;i>1;i--){
if(address[i]=='1')
value+=base;
base*=2;
}
return value;
}
/* number is valid and hex */
else if(result==2){
sscanf(address,"%x",&value);
return value;
}
/* number is valid and octal */
else if(result==4){
len = strlen(address);
for(i=0;i<len-2;i++)
newnumber[i] = address[i+2];
newnumber[i] = '