Professional Documents
Culture Documents
Your task for this lab is to write a program that extends the
simulation of the ARM processor and includes stack operations.
The program will have an array that represents the general ARM
registers, and a second multi-dimensional array that represents
memory. The program must also have allocated stack space within
the memory array.
The program will read content into the memory array from a file,
execute the instructions it finds in the array one instruction at a
time, and print the contents of the registers (including a program
counter) and stack after each instruction. Note, when printing the
stack do not print anything below the stack pointer, or above your
stack base.
The program will implement the following instructions: ADD,
ADDI, SUBI, LDUR, STUR, B, BL, BR. And at least on
Conditional Branch instruction.
Instructions in memory will use the assembly mnemonics rather
than binary op codes.
Instruction arguments will be register aliases (ex. X0, X1, X2, …)
memory locations in the memory array (100, 104, …), or
immediate values (#-3, #5, #0, …).
The program should use the specific address - 200, as the default
address for the
start instructions in memory.
The stack must be at least 100 words deep. Make sure your stack will
not grow over your program/data area.
The program must have a check and a “Ran out of Stack Space/Stack
Overflow” error message.
Choose a high memory area for the stack.
The stack should grow down.
Stack memory locations should be on double word boundaries
(increment/decrement by 8).
Remember to initiate the stack pointer (SP) to the top of the stack.
Use BR XZR to halt the program.
Test Files:
Output
992: **
Hit enter for next instruction:>
Instruction executed: STUR X0, [SP, #0]
Registers: X0 = 512, SP=992, PC=212
Solution:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MEMORY_SIZE 1024 /* by default memory has size
1024 positions */
#define STACK_SIZE 256 /* size of stack */
#define FIELD_LEN 10 /* maximum length for an
instruction field string */
#define MAX_LINE_LEN 100 /* maximum length in a line */
};
/**
* Returns the last character in the string
*/
char lastchar(char *str)
{
return (str[strlen(str) - 1]);
}
/**
* Returns 1 if the given character represents a decimal digit, 0 otherwise
*/
int is_digit(char c)
{
/**
* Copies the string str2 to str1 removing the first char if fst=1 and
* removing the last char is lst = 1
*/
void copytrim(char *str1, char *str2, int fst, int lst)
{
/**
* Check if a string represents a valid int
*/
int valid_int(char *str)
{
int i = 0;
return (-1);
}
{
fclose(f); /* close file */
exit(EXIT_FAILURE);
}
}
printf("X%d", i);
}
printf("=%d",regs[i]);
first = 0;
}
}
if (!first)
printf(", ");
printf("PC=%d\n", PC);
printf("Stack:\t");
first = 1;
for (addr = MEMORY_SIZE; addr >= sp; addr-= 8)
{
if (!first)
printf(" \t");
printf("%6d: ", addr);
if (memused[addr])
printf("%d", atoi(memory[addr]));
printf("\n");
first = 0;
}
printf("Memory:\t");
first = 1;
for (addr = 0; addr < MEMORY_SIZE - STACK_SIZE; addr +=
4)
{
if (memused[addr])
{
printf("%d", atoi(memory[addr]));
printf("\n");
first = 0;
}
}
if (first)
printf("\n");
}
/**
* Gets the register number from the string if its a valid register Xn
* If not valid returns -1
*/
int get_register(char *reg)
{
int nreg;
/* initialize registers */
for (i = 0; i < 32; i++)
{
regs[i] = 0;
affected[i] = 0;
}
if (r1 != XZR)
{
regs[r1] = r;
}
affected[r1] = 1;
affected[r2] = 1;
affected[r3] = 1;
}
}
}
else if (!strcmp(opcode, "ADDI") || !strcmp(opcode,
"ADDIS"))
{
}
else
{
r3 = atoi(t3);
if (r2 == SP && (regs[r2] + r3 < MEMORY_SIZE
- STACK_SIZE))
{
printf("\n<< Stack overflow found at address %d
>>\n", PC - 4);
halt = -1; /* halt simulation */
}
}
}
}
}
else if (!strcmp(opcode, "B.EQ"))
{
if (!valid_int(op1))
{
printf("\n<< Invalid instruction operand at address
%d >>\n", PC - 4);
halt = -1; /* halt simulation */
}
else
{
r1 = atoi(op1);
if (r1 < 0 || r1 >= MEMORY_SIZE
|| (r1 & 3) != 0) /* if not aligned */
{
printf("\nEnd of simulation\n");
}
int main(int argc, char **argv)
{
int i;
char memory[MEMORY_SIZE][FIELD_LEN]; /*
memory array */
/* by default use code.txt as the input file */
char *filename = "code.txt";
return (EXIT_SUCCESS);
}