The document describes a homework assignment to simulate an ARM processor and implement stack operations. The program will read instructions from a file, execute them one by one, and print register and stack contents after each instruction. It will implement instructions like ADD, SUB, LOAD, STORE, BRANCH and handle a stack. The output will show the current instruction, register values and the used portion of the stack.
ENGLISH5 QUARTER4 MODULE1 WEEK1-3 How Visual and Multimedia Elements.pptx
C Homework Help
1. For any help regarding C Homework Help
visit : - https://www.programminghomeworkhelp.com/ ,
Email :- support@programminghomeworkhelp.com or
call us at :- +1 678 648 4277
2. Simulation of ARM Processor and Stack Operation
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.
programminghomeworkhelp.com
3. Load and store instructions will only use indirect addressing (ie. [Xn, #nn] ).
Branch instructions will use immediate or register addressing.
The program can limit the number of registers available for use in the program. At least 8
must be available, including X0, X1, X9, X10, SP (X28), LR (X30). Additional registers
may be implemented.
Data will be signed integers.
The Stack:
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:
programminghomeworkhelp.com
4. Students will create an input file to test their emulator. The program must be able
to read the name of the file as an argument
The instructions in the file to be executed must include:
At least one example of each instruction implemented.
At least 12 instructions.
Instructions to complete at least one loop.
At least one push and pop on the stack.
At least one function call.
Output
The output of the program will be a listing showing:
The current instruction
The values of any registers used in that instruction. Including the
Program Counter.
The portion of the stack which is in use – (note: this may be limited to
the current stack frame).
Additional information, such as the value of all registers, or other useful
items may be shown as well.
SAMPLE OUTPUT
Instruction executed: LDUR X0, XZR, #100
programminghomeworkhelp.com
5. Registers: X0 = 512, SP=1000, PC=204*
Stack: 1000: 98 ***
Hit enter for next instruction: >
Instruction executed: SUBI SP, SP, #8
Registers: SP=992, PC=208
Stack: 1000: 98
992: **
Hit enter for next instruction:>
Instruction executed: STUR X0, [SP, #0]
Registers: X0 = 512, SP=992, PC=212
programminghomeworkhelp.com
6. Stack: 1000: 4A
992: 512
Hit enter for next instruction: >
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 */
programminghomeworkhelp.com
7. /* definition of the register numbers */
enum {
X0 = 0, X1, X2, X3, X4, X5, X6, X7, X8, X9,
X10, X11, X12, X13, X14, X15, X16, X17, X18, X19,
X20, X21, X22, X23, X24, X25, X26, X27, X28, X29,
X30, X31, SP = 28, FP, LR, XZR
};
/**
* 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)
{
programminghomeworkhelp.com
8. return (c >= '0' && c <='9');
}
/**
* Returns 1 if the given character represents a whitespace char, 0
otherwise
*/
int is_space(char c)
{
return (c == ' ' || c == 'r' || c == 'n' || c == 't'
|| c == 'v' || c == 'f');
}
/**
* 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)
{
programminghomeworkhelp.com
9. if (fst == 1)
str2++;
strcpy(str1, str2);
if (lst == 1)
str1[strlen(str1) - 1] = 0;
}
/**
* Check if a string represents a valid int
*/
int valid_int(char *str)
{
int i = 0;
if (str[0] == '-' || str[0] == '+')
i++;
for (; i < strlen(str); i++)
if (!is_digit(str[i])) /* if not a digit,
is not a number */
return 0;
return (1);
}
programminghomeworkhelp.com
10. /**
* Split the instruction line by spaces, save the instruction in memory
*/
int save_instruction(char *inst,char mem[MEMORY_SIZE][FIELD_LEN], int nline)
{
char *ptr;
int nparts;
int address;
ptr = strtok(inst, " "); /* split string using spaces */
if (ptr == NULL) /* if can't split */
{
fprintf(stderr, "Error: line %d: invalid instruction formatn",
nline + 1);
return (-1); /* return error */
}
/* try to get the address */
if (sscanf(ptr, "%d", &address) != 1 || address <0 ||
address >= MEMORY_SIZE || (address & 3)) /* if error or
invalid address */
{
programminghomeworkhelp.com
11. fprintf(stderr, "Error: line %d: invalid addressn", nline + 1);
return (-1); /* return error */
}
ptr = strtok(NULL, " "); /* split next part using spaces */
nparts = 0; /* no parts initially */
while (ptr != NULL)
{
if (nparts >= 4) /* if too many parts */
{
fprintf(stderr, "Error: line %d: invalid instruction
formatn", nline + 1);
return (-1);
}
if (strlen(ptr) > FIELD_LEN) /* if field is too long */
{
fprintf(stderr, "Error: line %d: instruction field %d is too longn", nline +
1, nparts + 1);
return (-1);
}
programminghomeworkhelp.com
12. strcpy(mem[address + nparts], ptr); /* save field in memory */
nparts++; /* we have one more part */
ptr = strtok(NULL, " "); /* split next part of string using
spaces */
}
if (nparts == 0)
{
fprintf(stderr, "Error: line %d: invalid instruction formatn",
nline + 1);
return (-1);
}
if (address < 200) /*if data address*/
{
/* check for valid number */
if (!valid_int(mem[address]))
{
fprintf(stderr, "Error: line %d: invalid datan", nline + 1);
return (-1);
}
}
programminghomeworkhelp.com
13. return (0);
}
/**
* Load program code from a file and saves it in memory in the addresses
given
* as the first field in the line
*/
void load_program(char *filename, char mem[MEMORY_SIZE][FIELD_LEN])
{
FILE *f;
char buffer[MAX_LINE_LEN];
int nline;
f = fopen(filename, "rt"); /* open file for reading */
if (f == NULL) /* error opening */
{
fprintf(stderr, "Error: unable to open file "%s"n", filename);
exit(EXIT_FAILURE);
programminghomeworkhelp.com
14. }
printf("Loading program from "%s"n", filename);
/* read all lines in the file */
nline = 0; /* start at line 0 */
while (fgets(buffer, MAX_LINE_LEN, f) != NULL)
{
/* remove ending spaces and newline */
while (is_space(lastchar(buffer)))
buffer[strlen(buffer) - 1] = 0;
/* skip empty lines */
if (buffer[0] != 0)
{
/* save instruction in memory */
if (save_instruction(buffer, mem, nline) == -1) /* if error
*/
{
fclose(f); /* close file */
exit(EXIT_FAILURE);
}
}
programminghomeworkhelp.com
15. nline++; /* advance line number */
}
fclose(f); /* close the file */
}
/**
* Shows the contents of all changed registers
*/
void print_registers(int *regs, int *affected, int PC)
{
int i;
int first;
printf("Registers:t");
first = 1;
for (i = 0; i < 31; i++)
{
if (affected[i])
{
if (!first)
programminghomeworkhelp.com
16. printf(", ");
switch (i)
{
case SP:
printf("SP");
break;
case FP:
printf("FP");
break;
case LR:
printf("LR");
break;
default:
printf("X%d", i);
}
printf("=%d",regs[i]);
first = 0;
}
}
if (!first)
printf(", ");
printf("PC=%dn", PC);
programminghomeworkhelp.com
17. }
/**
* Prints the stack contents
*/
void print_stack(int sp, char memory[MEMORY_SIZE][FIELD_LEN],
int memused[MEMORY_SIZE])
{
int addr;
int first;
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;
}
programminghomeworkhelp.com
18. if (first)
printf("n");
}
/**
* Prints the memory
*/
void print_memory(char memory[MEMORY_SIZE][FIELD_LEN], int
memused[MEMORY_SIZE])
{
int addr;
int first;
printf("Memory:t");
first = 1;
for (addr = 0; addr < MEMORY_SIZE - STACK_SIZE; addr += 4)
{
if (memused[addr])
{
programminghomeworkhelp.com
19. if (!first)
printf(" t");
printf("%6d: ", 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;
programminghomeworkhelp.com
20. if (!strcmp(reg, "SP"))
nreg = SP;
else if (!strcmp(reg, "FP"))
nreg = FP;
else if (!strcmp(reg, "LR"))
nreg = LR;
else if (!strcmp(reg, "XZR"))
nreg = XZR;
else if (sscanf(reg, "X%d", &nreg) != 1)
return (-1);
if (nreg < 0 || nreg > 31)
return (-1);
return (nreg);
}
/**
* Simulates the program in memory starting at address 200
*
*/
void simulate_program(char memory[MEMORY_SIZE][FIELD_LEN])
{
programminghomeworkhelp.com
21. int PC;
int regs[32]; /* registers */
int affected[32]; /* registers affected */
int flagZ;
int memused[MEMORY_SIZE];
char *opcode, *op1, *op2, *op3;
char t1[FIELD_LEN];
char t2[FIELD_LEN];
char t3[FIELD_LEN];
int i;
int r1, r2, r3, r;
int halt;
PC = 200; /* start simulating at address 200 */
/* initialize registers */
for (i = 0; i < 32; i++)
{
regs[i] = 0;
affected[i] = 0;
}
programminghomeworkhelp.com
22. regs[SP] = MEMORY_SIZE; /* stack top at end of memory */
/* initialize memory used */
for (i = 0; i < MEMORY_SIZE; i++)
{
memused[i] = 0;
}
flagZ = 0; /* initialize flags */
printf("Starting simulation...n");
halt = 0;
while (!halt) /* repeat until halt is found */
{
opcode = memory[PC]; /* fetch instruction */
op1 = memory[PC + 1]; /* fetch operands */
op2 = memory[PC + 2];
op3 = memory[PC + 3];
PC+=4; /* advance to next instruction */
programminghomeworkhelp.com
23. /* clear affected registers */
for (i = 0; i < 31; i++)
affected[i] = 0;
if (!strcmp(opcode, "ADD") || !strcmp(opcode, "ADDS"))
{
if (lastchar(op1) != ',' || lastchar(op2) != ',')
{
printf("n<< Invalid instruction operand at address %d >>n", PC -
4);
halt = -1; /* halt simulation */
}
else
{
copytrim(t1, op1, 0, 1);
copytrim(t2, op2, 0, 1);
r1 = get_register(t1);
r2 = get_register(t2);
r3 = get_register(op3);
if (r1 == -1 || r2 == -1 || r3 == -1)
{
programminghomeworkhelp.com
24. printf("n<< Invalid instruction operand at address
%d >>n", PC - 4);
halt = -1; /* halt simulation */
}
else
{
r = regs[r2] + regs[r3];
/* if S instruction, update flag */
if (lastchar(opcode) == 'S')
flagZ = (r == 0);
if (r1 != XZR)
{
regs[r1] = r;
}
affected[r1] = 1;
affected[r2] = 1;
affected[r3] = 1;
}
}
}
else if (!strcmp(opcode, "ADDI") ||
!strcmp(opcode, "ADDIS"))
{
programminghomeworkhelp.com
25. if (lastchar(op1) != ',' || lastchar(op2) != ',' || op3[0] != '#')
{
printf("n<< Invalid instruction operand at address
%d >>n", PC - 4);
halt = -1; /* halt simulation */
}
else
{
copytrim(t1, op1, 0, 1);
copytrim(t2, op2, 0, 1);
copytrim(t3, op3, 1, 0);
r1 = get_register(t1);
r2 = get_register(t2);
if (r1 == -1 || r2 == -1 || !valid_int(t3))
{
printf("n<< Invalid instruction operand at address
%d >>n", PC - 4);
halt = -1; /* halt simulation */
}
else
{
programminghomeworkhelp.com
26. r3 = atoi(t3);
r = regs[r2] + r3;
/* if S instruction, update flag */
if (lastchar(opcode) == 'S')
flagZ = (r == 0);
if (r1 != XZR)
regs[r1] = r;
affected[r1] = 1;
affected[r2] = 1;
}
}
}
else if (!strcmp(opcode, "SUBI") || !strcmp(opcode, "SUBIS"))
{
if (lastchar(op1) != ',' || lastchar(op2) != ',' || op3[0] !=
'#')
{
printf("n<< Invalid instruction operand at address %d
>>n", PC - 4);
halt = -1; /* halt simulation */
programminghomeworkhelp.com
27. }
else
{
copytrim(t1, op1, 0, 1);
copytrim(t2, op2, 0, 1);
copytrim(t3, op3, 1, 0);
r1 = get_register(t1);
r2 = get_register(t2);
if (r1 == -1 || r2 == -1 || !valid_int(t3))
{
printf("n<< Invalid instruction operand at address
%d >>n", PC - 4);
halt = -1; /* halt simulation */
}
else
{
r3 = atoi(t3);
r = regs[r2] - r3;
/* if S instruction, update flag */
if (lastchar(opcode) == 'S')
flagZ = (r == 0);
programminghomeworkhelp.com
29. if (r1 == -1 || r2 == -1 || !valid_int(t3))
{
printf("n<< Invalid instruction operand at address %d >>n", PC - 4);
halt = -1; /* halt simulation */
}
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 (r2 == SP && ((regs[r2] + r3) & 7) != 0)
{
printf("n<< Misaligned stack access found at address %d >>n", PC - 4);
halt = -1; /* halt simulation */
}
else if (regs[r2] + r3 < 0 || regs[r2] + r3 >= MEMORY_SIZE
programminghomeworkhelp.com
30. || ((regs[r2] + r3) & 3) != 0 /* if not aligned */
|| !valid_int(memory[regs[r2] + r3]))
{
printf("n<< Invalid memory access found at address %d >>n", PC - 4);
halt = -1; /* halt simulation */
}
else
{
memused[regs[r2] + r3] = 1;
if (r1 != XZR)
regs[r1] = atoi(memory[regs[r2] + r3]);
affected[r1] = 1;
affected[r2] = 1;
}
}
}
}
else if (!strcmp(opcode, "STUR"))
{
if (lastchar(op1) != ',' || lastchar(op2) != ',' || op2[0] != '['
|| op3[0] != '#' || lastchar(op3) != ']')
{
printf("n<< Invalid instruction operand at address %d >>n", PC - 4);
programminghomeworkhelp.com
31. halt = -1; /* halt simulation */
}
else
{
copytrim(t1, op1, 0, 1);
copytrim(t2, op2, 1, 1);
copytrim(t3, op3, 1, 1);
r1 = get_register(t1);
r2 = get_register(t2);
if (r1 == -1 || r2 == -1 || !valid_int(t3))
{
printf("n<< Invalid instruction operand at address %d >>n", PC - 4);
halt = -1; /* halt simulation */
}
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 */
}
programminghomeworkhelp.com
32. else if (r2 == SP && ((regs[r2] + r3) & 7) != 0)
{
printf("n<< Misaligned stack access found at address %d >>n", PC - 4);
halt = -1; /* halt simulation */
}
else if (regs[r2] + r3 < 0 || regs[r2] + r3 >= MEMORY_SIZE
|| ((regs[r2] + r3) & 3) != 0 /* if not aligned */
|| !valid_int(memory[regs[r2] + r3]))
{
printf("n<< Invalid memory access found at address %d >>n", PC - 4);
halt = -1; /* halt simulation */
}
else
{
memused[regs[r2] + r3] = 1;
sprintf(memory[regs[r2] + r3], "%d", regs[r1]);
affected[r1] = 1;
affected[r2] = 1;
}
}
}
}
programminghomeworkhelp.com
33. else if (!strcmp(opcode, "B"))
{
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("n<< Invalid memory access found at address %d >>n", PC - 4);
halt = -1; /* halt simulation */
}
else
{
PC = r1;
}
}
}
programminghomeworkhelp.com
34. else if (!strcmp(opcode, "BL"))
{
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("n<< Invalid memory access found at address %d >>n", PC - 4);
halt = -1; /* halt simulation */
}
else
{
regs[LR] = PC;
PC = r1;
affected[LR] = 1;
}
programminghomeworkhelp.com
35. }
}
else if (!strcmp(opcode, "BR"))
{
r1 = get_register(op1);
if (r1 == -1)
{
printf("n<< Invalid instruction operand at address %d >>n", PC - 4);
halt = -1; /* halt simulation */
}
else
{
if (regs[r1] < 0 || regs[r1] >= MEMORY_SIZE
|| (regs[r1] & 3) != 0) /* if not aligned */
{
printf("n<< Invalid memory access found at address %d >>n", PC - 4);
halt = -1; /* halt simulation */
}
programminghomeworkhelp.com
36. else
{
PC = regs[r1];
affected[r1] = 1;
if (r1 == XZR)
halt = 1; /* BR XZR halts the program */
}
}
}
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 */
{
programminghomeworkhelp.com
37. printf("n<< Invalid memory access found at address %d >>n", PC - 4);
halt = -1; /* halt simulation */
}
else
{
if (flagZ)
PC = r1;
}
}
}
else if (!strcmp(opcode, "B.NE"))
{
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 */
programminghomeworkhelp.com
38. {
printf("n<< Invalid memory access found at address %d >>n", PC - 4);
halt = -1; /* halt simulation */
}
else
{
if (!flagZ)
PC = r1;
}
}
}
else /*if invalid opcode */
{
printf("n<< Invalid instruction at address %d >>n", PC - 4);
halt = -1; /* halt simulation */
}
if (halt != -1)
{
printf("nInstruction executed:t%s %s %s %sn",opcode, op1,
op2, op3);
programminghomeworkhelp.com
39. print_registers(regs, affected, PC);
print_stack(regs[SP], memory, memused);
print_memory(memory, memused);
printf("nHit enter for next instruction: >");
fflush(stdout);
getchar();
}
}
printf("nEnd of simulationn");
}
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";
if (argc >= 2) /* if an input file was given */
filename = argv[1]; /* use it as the input filename */
programminghomeworkhelp.com
40. /* clear memory */
for (i = 0; i < MEMORY_SIZE; i++)
strcpy(memory[i], "0");
/* load program from file */
load_program(filename, memory);
/* simulate the program in memory */
simulate_program(memory);
return (EXIT_SUCCESS);
}
programminghomeworkhelp.com