Tip of the day
News
Instructions
Objective
After the blip in the Marvel Universe https://marvelcinematicuniverse.fandom.com/wiki/Blip, we can’t couldn’t remember if we’d given you this assignment before. So we are redoing
assignment 4, but in assembly!In Assignment 4, you wrote a program to simulate The Game of Life in C. For this assignment, you will be implementing doRow function from that assignment but in assembly. If your doRow does not work as specified below and/or does not work, you should start by fixing your C code. Even if your original C code for doRow works it may be worthwhile to consider how to simplify it for assembly.
- Write your code in doRow.S .
- Assume non-degenerate input.
- We have provided correct implementations of the other Life functions as library.
functions. Your version of doRow MUST work with our library function simLoop.
Look at Assignment 6 and the Style Guide for examples to write/modify the prolog and
epilog.
- The parameters doRow will receive from our version of simLoop are exactly as outlined below. [See Assignment 4 writeup for full details on Life]
- Remember to push and pop to the stack as per calling convention
Requirements and Specifications
In order to run your program, you MUST ssh into the pi-cluster from ieng6 or be on a campus network or VPN. Both your ieng6 and pi cluster account share the same files, so anything you copy onto the lab machines (scp to ieng6) will ALSO be on the pi-cluster when you ssh in. GIT only works from ieng6 since the pi-cluster is on an internal network.
From Your Personal Computer :
- Open a Terminal
- ssh into your ieng6 account
- git clone the starter code (link)
- ssh into the pi-cluster using the following command:
- You are ready to start! (REMEMBER: To do your ARM assignment you need to get back to your local machine!)
$ ssh
ex: $ ssh cs30sp20xx@pi-cluster
Source Code
A4 sim(do row function)
/** * Assignment: life * Name: Ramtin Kazemi * PID: A16567965 * Class: UCSD CSE30-SP21 * */#include <sim.h>#define CIMPextern void asm_doRow(belem*, belem*, size_t, size_t, size_t);/** * gets x mod N (works for negative numbers as well! Use this instead of %) */size_t getModVal(int x, size_t N) { size_t adj = x / N; return ((x + adj * N) % N);}/** * process one row of the board */static void doRow(belem* dest, belem* src, size_t row, size_t rows, size_t cols) { for (int i = 0; i < cols; i++) { int count = 0; if (row == 0) { if (src[(row + 1) * cols + i] - '0') { count++; } if (src[(rows - 1) * cols + i] - '0') { count++; } if (i == 0 || i > cols - 1) { if (src[row * cols + i + 1] - '0') { count++; } if (src[rows - 1 * cols + i + 1] - '0') { count++; } if (src[row + 1 * cols + i + 1] - '0') { count++; } if (i == 0) { if (src[row * cols + cols - 1] - '0') { count++; } if (src[rows - 1 * cols + cols - 1] - '0') { count++; } if (src[row + 1 * cols + cols - 1] - '0') { count++; } } else { if (src[row * cols + i - 1] - '0') { count++; } if (src[row + 1 * cols + i - 1] - '0') { count++; } if (src[rows - 1 * cols + i - 1] - '0') { count++; } } } else if (i == cols - 1) { if (src[row * cols + i - 1] - '0') { count++; } if (src[row + 1 * cols + i - 1] - '0') { count++; } if (src[rows - 1 * cols + i - 1] - '0') { count++; } if (src[0 * cols + 0] - '0') { count++; } if (src[rows - 1 * cols + 0] - '0') { count++; } if (src[1 * cols + 0] - '0') { count++; } } } else if (row == rows - 1) { if (src[row - 1 * cols + i] - '0') { count++; } if (src[0 * cols + i] - '0') { count++; } if (i == 0 || i > cols - 1) { if (src[row * cols + i + 1] - '0') { count++; } if (src[row - 1 * cols + i + 1] - '0') { count++; } if (src[0 * cols + i + 1] - '0') { count++; } if (i == 0) { if (src[0 * cols + cols - 1] - '0') { count++; } if (src[row - 1 * cols + cols - 1] - '0') { count++; } if (src[row * cols + cols - 1] - '0') { count++; } } else { if (src[row * cols + i - 1] - '0') { count++; } if (src[row - 1 * cols + i - 1] - '0') { count++; } if (src[0 * cols + i - 1] - '0') { count++; } } } else if (i == cols - 1) { if (src[row * cols + i - 1] - '0') { count++; } if (src[0 * cols + i - 1] - '0') { count++; } if (src[row - 1 * cols + i - 1] - '0') { count++; } if (src[0 * cols + 0] - '0') { count++; } if (src[row - 1 * cols + 0] - '0') { count++; } if (src[row * cols + 0] - '0') { count++; } } } else { if (src[row + 1 * cols + i] - '0') { count++; } if (src[rows - 1 * cols + i] - '0') { count++; } if (i == 0 || i > cols - 1) { if (src[row * cols + i + 1] - '0') { count++; } if (src[row - 1 * cols + i + 1] - '0') { count++; } if (src[row + 1 * cols + i + 1] - '0') { count++; } if (i == 0) { if (src[row * cols + cols - 1] - '0') { count++; } if (src[row - 1 * cols + cols - 1] - '0') { count++; } if (src[row + 1 * cols + cols - 1] - '0') { count++; } } else { if (src[row * cols + i - 1] - '0') { count++; } if (src[row + 1 * cols + i - 1] - '0') { count++; } if (src[rows - 1 * cols + i - 1] - '0') { count++; } } } else if (i == cols - 1) { if (src[row * cols + i - 1] - '0') { count++; } if (src[row + 1 * cols + i - 1] - '0') { count++; } if (src[row - 1 * cols + i - 1] - '0') { count++; } if (src[row * cols + 0] - '0') { count++; } if (src[rows - 1 * cols + 0] - '0') { count++; } if (src[row + 1 * cols + 0] - '0') { count++; } } } if (src[row * cols + i] - '0') { if (count == 0 || count == 1) { dest[row * cols + i] = '0'; } else if (count >= 4) { dest[row * cols + i] = '0'; } } else { if (count == 3) { dest[row * cols + i] = '1'; } } }}/** * perform a simulation for "steps" generations * * for steps * calculate the next board * swap current and next */void simLoop(boards_t* self, unsigned int steps) { for (int i = 0; i < steps ; i++) { //Make: warning: comparison of integer expressions of different signedness: 'int' and 'size_t'?? for (size_t j = 0; j < self->numRows; j++) { doRow(self->nextBuffer, self->currentBuffer, j, self->numRows, self->numCols); } swapBuffers(self); self->gen++; }}A4 Board/** * Assignment: life * Name : Ramtin Kazemi * PID: A16567965 * Class: UCSD CSE30-SP21 * */#include "cse30life.h"#include "board.h"/** * create a new board * * - malloc a boards structure * - set the generation to 0 * - open the file (if it doesn't exist, return a NULL pointer * - read the first line which is the number of rows * - read the second line which is the number of cols * - set the # of rows and # of cols in the boards structure * - malloc bufferA and bufferB * - Set currentBuffer and nextBuffer * - clear both board buffers * - read the file until done. each row contains a row and a columns separted * by * white space * for each line, set the cell in the current buffer * - close the file * - return the boards pointer if successfull or NULL ptr otherwise */boards_t *createBoard(char *initFileName) { boards_t *board = malloc(sizeof(boards_t)); FILE *file; if ((file = fopen(initFileName, "r")) == NULL) { return NULL; } int temp = 0,temp1 = 0, num1 = 0, num2 = 0; fscanf(file, "%d", &temp); board->numCols = 0; board->numRows=0; if(temp<3){ return NULL; } fgetc(file); fscanf(file, "%d", &temp1); if(temp1<3){ return NULL; } board->numCols = temp1; board->numRows = temp; //causd memory leak! board->bufferA =malloc(sizeof(belem) * (board->numCols * board->numRows)); //caused memory leak! board->bufferB =malloc(sizeof(belem) * (board->numCols * board->numRows)); board->gen = 0; clearBoards(board); board->currentBuffer = board->bufferA; board->nextBuffer = board->bufferB; while (fscanf(file, "%d%d", &num1, &num2) > 0) { size_t index = getIndex(board->numCols,num1,num2); board->currentBuffer[index] = '1'; board->nextBuffer[index]='1'; fgetc(file); } fclose(file); file=NULL; free(file); initFileName=NULL; free(initFileName); return board;}/** * delete a board */void deleteBoard(boards_t **bptrPtr) { free((*bptrPtr)->bufferA); free((*bptrPtr)->bufferB); (*bptrPtr)->bufferA=NULL; (*bptrPtr)->bufferB=NULL; //GradeScope: allocs: 7 frees: 9 bytes allocated: 9370 errors: 2. fixed after taking out these two lines //free((*bptrPtr)->currentBuffer); //free((*bptrPtr)->nextBuffer); (*bptrPtr)->currentBuffer=NULL; (*bptrPtr)->nextBuffer=NULL; free(*bptrPtr); *bptrPtr = NULL;}/** * set all the belems in both buffers to 0 */void clearBoards(boards_t *self) { for (size_t i = 0; i < self->numRows; i++) { for (size_t j = 0; j < self->numCols; j++) { size_t r = getIndex(self->numCols,i,j); self->bufferA[r] = 0; self->bufferB[r] = 0; } }}/** * swap the current and next buffers */void swapBuffers(boards_t *self) { //"no for loops are needed, just a regular temp swap as mentioned in the lecture week2 or 3" //for (size_t i = 0; i < self->numRows; i++) { //for (size_t j = 0; j < self->numCols; j++) { //size_t r = getIndex(self->numCols,i,j); belem *temp = NULL; temp = self->currentBuffer; self->currentBuffer = self->nextBuffer; self->nextBuffer = temp; //} //}}/** * get a cell index */size_t getIndex(size_t numCols, size_t row, size_t col) { return (row * numCols + col); //given in the write up}doRow in ARM assembly language .arch armv7 .cpu cortex-a53 .equ NUL, 0 .global asm_doRow // !!! SET FP_OFFSET TO THE NUMBER OF (SAVED REGISTERS -1 * 4) // TODO - ADJUST FOR CALLEE SAVED REGISTERS .equ FP_OFFSET, 32 // (# of saved regs - 1) * 4 .equ NCOLS_OFFSET, 4 // number columns (5th parameter) // TODO - ALLOCATE LOCAL SPACE or PARAMETER SPACE // (you can save incoming parameters in either one) .equ LOCAL_SPACE, 0 // total local space .equ PARAM_SPACE, 0 // total param space // TODO define your local variable offsets here // offsets are referenced to the framepointer. .equ XX_OFFSET, 0asm_doRow: push {r4-r10, fp, lr} add fp, sp, #FP_OFFSET sub sp, sp, #(LOCAL_SPACE + PARAM_SPACE) mov r4, r0 // save buffer pointers mov r5, r1 mov r6, r2 // save row ldr r7, [fp, #NCOLS_OFFSET] // load cols // set cols and rows mov r0, r3 mov r1, r7 bl setNRowsNCols mov r7, #0 // for (col = 0; col < cols; col++) {forCol: mov r8, #0 // count = 0; mov r9, #-1 // for (i = -1; i <= 1; i++) {fori: mov r10, #-1 // for (j = -1; j <= 1; j++) {forj: cmp r9, #0 // if (i != 0 || j != 0 ) { bne if1 cmp r10, #0 beq nextjif1: // get index mov r0, r6 // load row add r0, r0, r9 // row + i mov r1, r7 // load col add r1, r1, r10 // col + j bl nGetIndexRC // index = nGetIndexRC(row+i, col+j); ldrb r1, [r5, r0] // load src[index] add r8, r8, r1 // count += src[index];nextj: add r10, r10, #1 // j++ cmp r10, #1 // repeat if j<=1 ble forj add r9, r9, #1 // i++ cmp r9, #1 // repeat if i<=1 ble fori // get index mov r0, r6 // load row mov r1, r7 // load col bl nGetIndexRC // index = nGetIndexRC(row, col); ldrb r1, [r5, r0] // load src[index]if2: cmp r1, #0 // if (src[index] != 0) beq else2if3: cmp r8, #2 // if (count < 2) { bge elseif3 mov r2, #0 // dest[index] = 0; b saveDestelseif3: cmp r8, #4 // else if (count < 4) { bge else3 mov r2, #1 // dest[index] = 1; b saveDestelse3: mov r2, #0 // else dest[index] = 0; b saveDestelse2:if4: cmp r8, #3 // if (count == 3) { bne else4 mov r2, #1 // dest[index] = 1; b saveDestelse4: mov r2, #0 // else dest[index] = 0;saveDest: strb r2, [r4, r0] // save dest[index] add r7, r7, #1 // col++ ldr r0, [fp, #NCOLS_OFFSET] // load cols cmp r7, r0 // if col < cols blt forCol // repeat for sub sp, fp, #FP_OFFSET pop {r4-r10, fp, lr} bx lrFinal program/** * Assignment: life * Name: Ramtin Kazemi * PID: A16567965 * Class: UCSD CSE30-SP21 * */#include <sim.h>#define CIMPextern void asm_doRow(belem *, belem *, size_t, size_t, size_t);/** * gets x mod N (works for negative numbers as well! Use this instead of %) */size_t getModVal(int x, size_t N){ size_t adj = x/N; return((x+adj*N)%N);}/** * process one row of the board */static void doRow(belem *dest, belem *src, size_t row, size_t rows, size_t cols){ size_t col; int i,j; size_t r, c; size_t count; size_t index; for (col = 0; col < cols; col++) { count = 0; for (i = -1; i <= 1; i++) { r = getModVal(row + i, rows); for (j = -1; j <= 1; j++) { c = getModVal(col + j, cols); if (i != 0 || j != 0 ) { index = getIndex(cols, r, c); count += src[index]; } } } index = getIndex(cols, row, col); if (src[index] != 0) { if (count < 2) { dest[index] = 0; } else if (count < 4) { dest[index] = 1; } else dest[index] = 0; } else { if (count == 3) { dest[index] = 1; } else dest[index] = 0; } }}/** * perform a simulation for "steps" generations * * for steps * calculate the next board * swap current and next */void simLoop(boards_t *self, unsigned int steps){ unsigned step; size_t row; for (step = 0; step < steps; step++) { for (row = 0; row < self->numRows; row++) doRow(self->nextBuffer, self->currentBuffer, row, self->numRows, self->numCols); swapBuffers(self); self->gen++; }}
Related Samples
Explore our Assembly Language Assignments samples, meticulously crafted to demystify low-level programming. From basic instructions to intricate system calls, each sample elucidates hardware interactions and optimization strategies. Ideal for students delving into computer architecture and embedded systems, fostering proficiency in assembly programming.
Assembly Language
Word Count
11673 Words
Writer Name:Dr. Denise M. Lopez
Total Orders:500
Satisfaction rate:
Assembly Language
Word Count
3655 Words
Writer Name:Dr. John L. Sanders
Total Orders:900
Satisfaction rate:
Assembly Language
Word Count
11176 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
1782 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
7747 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
2371 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
1270 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
5650 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
5768 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
1586 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
2204 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
3452 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
6803 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
5272 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
2752 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
10514 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
2587 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
15048 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
4268 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate:
Assembly Language
Word Count
4470 Words
Writer Name:Rehana Magnus
Total Orders:750
Satisfaction rate: