×
Samples Blogs Make Payment About Us Reviews 4.9/5 Order Now

Contrived Version "Mastermind" Game Armv8 Assembly Language Assignment Solution.

June 25, 2024
Rehana Magnus
Rehana Magnus
🇨🇦 Canada
Assembly Language
Rehana Magnus, PhD in Computer Science from the esteemed Acadia Institute of Technology, Canada. With 6 years of experience, specializes in assembly language programming. Proficient in low-level coding, optimizing performance, and enhancing system functionality.
Key Topics
  • Instructions
  • Requirements and Specifications
Tip of the day
Familiarize yourself with OCaml's pattern matching; it simplifies handling recursive data structures like lists and trees, making your code concise and easier to debug.
News
In 2024, Girls Who Code introduced a Data Science + AI track in their free summer programs for high school students, fostering skills in cybersecurity and creative coding​

Instructions

Objective

Write a program in ARMv8 assembly language to create a contrived version of the “Mastermind” game.

Requirements and Specifications

Write an assembly language assignment where game is a contrived version of Mastermind: the computer hides a NxM color code chosen fromC colors. The user tries to crack the hidden code by taking several steps. The first step is for the user to make a guess. The computer responds by providing feedback hints. The game ends when the user:

  1. cracks the game,
  2. reaches a maximum number of trials R without cracking the hidden code, or
  3. choses to quit the game. The game will also end if the timer is exhausted before cracking the code.
  4. Screenshots of output

    program to make contrived version of mastermind game in assembly language

    Source Code

    define(argvr,x19) define(N,x20) define(M,x21) define(C,x22) define(R,x23) define(remaining,x24) define(duration,x25) define(playerName,x26) define(guess,x27) define(try,x28) define(code,x19) define(S, d8) .equ lasttime, 0 .equ win, 8 .equ mode, 12 .equ trhead, 16 .equ transFilename, 24 .equ buffer, 56 .text helloMsg: .string "Hello %s!\n" testGameMsg: .string "Running Mastermind in test `mode'\n" playGameMsg: .string "Running Mastermind in play `mode'\n" hiddenMsg: .string "Hidden `code' is: " startMsg: .string "\nStart cracking...\n" usageMsg: .string "Usage:\n %s name `N' `M' `C' `R' `mode' [`duration']\n" invArgsMsg: .string "Invalid command line argument.\n" colorFmt: .string "%c " hiddenFmt: .string "- " hintHeader: .string "B W `R' `S' T\n" hintBW: .string "%-2d %-2d " hintRST: .string "%-2d %.2f %d:%02d\n" newline: .string "\n" badInputMsg: .string "Invalid input. Please `try' again\n" wonMsg: .string "Cracked!\n" lostMsg: .string "You lost!\n" scoreMsg: .string "Final score: %.2f\n" showTopMsg: .string "Show bottom/top scores (B/T/`N')? " askAgainMsg: .string "Play again (Y/`N')? " logFilename: .string "scores.log" logWMode: .string "a" logRMode: .string "r" logFmt: .string "%-20s %-12.2f %d:%02d\n" logInf: .string "%-20s %-12.2f %-12.2f\n" intFmt: .string "%d" promptN: .string "Number of scores to print?: " topScoresMsg: .string "\nTop %d Scores:\n" botScoresMsg: .string "\nBottom %d Scores:\n" scoresHeader: .string "Name Score Time (s)\n" transFileFmt: .string "%s-%d.txt" transWMode: .string "wt" infinity: .dword 0x7FF0000000000000 .balign 4 .global main .type main, %function main: stp fp, lr, [sp, -16]! // save registers in stack mov fp, sp sub sp, sp, 256 // allocate space for variables mov argvr, x1 // save argv pointer in register mov duration, 0 // clear duration cmp x0, 7 // if n arguments < 7 blt badArguments // exit with error cmp x0, 8 // compare number of arguments with 8 blt grabInputs // if < 8, read inputs ldr x0, [argvr, 56] // load time string from arguments bl atoi // convert to integer mov duration,x0 // save in time register grabInputs: ldr playerName, [argvr, 8] // load player name pointer in register ldr x0, [argvr, 16] // load N string from arguments bl atoi // convert to integer uxtw x0, w0 // extend to x0 mov N, x0 // save in N register ldr x0, [argvr, 24] // load M string from arguments bl atoi // convert to integer uxtw x0, w0 // extend to x0 mov M, x0 // save in M register ldr x0, [argvr, 32] // load C string from arguments bl atoi // convert to integer uxtw x0, w0 // extend to x0 mov C, x0 // save in M register ldr x0, [argvr, 40] // load R string from arguments bl atoi // convert to integer uxtw x0, w0 // extend to x0 mov R, x0 // save in R register ldr x0, [argvr, 48] // load mode string from arguments bl atoi // convert to integer str w0, [sp, mode] // save in mode variable cmp C,5 // check if C >= 5 blt invalidArguments // if not, print error cmp R,1 // check if R >= 1 blt invalidArguments // if not, print error cmp M,C // check if M<=C bgt invalidArguments // if not, print error ldr w0, [sp, mode] // load mode cmp w0, 0 // check if mode is 0 blt invalidArguments // if <0, print error cmp w0, 1 // check if mode is 1 bgt invalidArguments // if >1, print error mov x0,0 bl time // Set the time seed for the random number generator bl srand // Call the srand function to initialize seed cmp duration, 0 // if no duration was given bne continue // if duration is set, continue mov x0, 5 // multiply N by 5 mul duration, N, x0 // set duration = N*5 continue: mul x0, N, M // multiply n*m bl malloc // allocate space for code mov code, x0 // save in code mul x0, N, M // multiply n*m bl malloc // allocate space for guess mov guess, x0 // save in guess gameStart: str xzr, [sp, trhead] // initialize history list to zero mov x0, code // save in code mov x1, N // use N mov x2, M // use M mov x3, C // use colors mov x4, guess // use guess bl initializeGame // generate initial game ldr x0, =helloMsg // load hello message address mov x1, playerName // load player name address bl printf // print the hello message ldr w0, [sp, mode] // load mode cmp w0, 0 // check if mode is play beq startPlay // if play, start ldr x0, =testGameMsg // else, print it's a test game bl printf ldr x0, =hiddenMsg // print hidden message bl printf mov x0, code // load code mov x1, N // use N mov x2, M // use M bl printCode // print initial code ldr x0, =newline // print newline bl printf startPlay: bl showScores // ask if scores should be shown ldr x0, =startMsg // load address of start message bl printf // print start message mov x0, 60 // 60 seconds per minute mul remaining, duration, x0 // remaining = duration*60 mov try, 1 // current try ucvtf S, xzr // clear score str wzr, [sp, win] // not winning yet mov x0, code // load code mov x1, N // use N mov x2, M // use M add x3, sp, trhead bl printHidden // print hidden hint gameLoop: mov x0, guess // save in guess mov x1, N // use N mov x2, M // use M mov x3, C // use C bl readInput // read guess from user cmp w0, -1 // if exit beq dropGame // drop the game cmp w0, 0 // if error bne checkGuess // if no error, check guess ldr x0, =badInputMsg // load address of error message bl printf // print error message b gameLoop // read again checkGuess: mov x0, guess // load guess mov x1, N // use N mov x2, M // use M add x3, sp, trhead bl printGuess // print guess mov x0, guess // pass guess mov x1, code // pass code mov x2, N // pass N mov x3, M // pass M add x4, sp, trhead bl displayHints // display the hints mul x2, N, M cmp x0, x2 // see if guess it's exact bne addScore // if not, add score mov w2, 1 str w2, [sp, win] // else, set win to 1 addScore: ucvtf d0, x0 // convert B to float ucvtf d1, x1 // convert W to float ucvtf d2, try // convert R to float fmov d3, 2.0 // divide by 2 fdiv d1, d1, d3 // W/2 fadd d0, d0, d1 // B+W/2 fdiv d0, d0, d2 // (B+W/2)/R fadd S, S, d0 // add to score mov x0, 100 // load 100.0 ucvtf d1, x0 fmul S, S, d1 // round to 100 frinta S, S fdiv S, S, d1 mov x0, xzr bl time // get current time uxtw x0, w0 cmp try, 1 // check if it's the first try beq skip // if so, don't update remaining time ldr x1, [sp, lasttime] // load last time sub x1, x0, x1 // time difference sub remaining, remaining, x1 // get new remaining time skip: str x0, [sp, lasttime] // save time as last time cmp remaining, 0 // check if remaining is above zero bgt getMinSec // if so, get min :sec mov remaining, 0 // else, clear remaining time getMinSec: mov x0, 60 // 60 seconds per minute udiv x3, remaining, x0 // remaining/60 msub x4, x3, x0, remaining // calculate remainder mov x2, try // load R fmov d0, S // load current score add x0, sp, buffer ldr x1, =hintRST // load format to print R, S and T bl sprintf // print R, S and T add x0, sp, buffer add x1, sp, trhead bl saveString // print R, S, T ldr w0, [sp, win] // load win status cmp w0, 1 // if win beq gameCracked // end game cmp remaining, 0 // if no time beq gameLost // end game add try, try, 1 // increment number of tries cmp try, R // compare with maximum tries ble gameLoop // repeat game loop if <= max tries gameLost: ldr x0, =lostMsg // print lost message bl printf fmov d0, S // get current score mov x0, try // get try mov x1, remaining // get remaining time bl calculateScore // get last score fneg d8, d0 // convert to negative b printScore gameCracked: ldr x0, =wonMsg // print won message bl printf fmov d0, S // get current score mov x0, try // get try mov x1, remaining // get remaining time bl calculateScore // get last score fmov d8, d0 // save score printScore: ldr x0, =scoreMsg // print score message fmov d0, d8 bl printf mov x0, playerName // load player name fmov d0, d8 // load score ucvtf d1, remaining // convert remaining to float bl logScore mov x0, xzr bl time // get current time mov w3, w0 add x0, sp, transFilename ldr x1, =transFileFmt // mov x2, playerName bl sprintf add x0, sp, transFilename add x1, sp, trhead bl transcriptGame // save the transcript add x0, sp, trhead bl freeTranscript // free the transcript bl showScores // show scores ldr x0, =askAgainMsg // ask if new game should be started bl printf bl readChar // read input cmp w0, 'Y' // if new game beq gameStart // restart cmp w0, 'y' // if new game beq gameStart // restart b endGame // end game dropGame: mov x0, playerName // load player name ldr x1, =infinity ldr d1, [x1] // load time +inf fmov d0, d1 // load score -inf fneg d0, d0 bl logScore endGame: mov x0, code // free allocated space for code mov x1, guess // free allocated space for guess bl exitGame // exit game badArguments: ldr x0, =usageMsg // print usage message ldr x1, [argvr] // load first argument (program name) bl printf b terminate // terminate program invalidArguments: ldr x0, =invArgsMsg // print error message bl printf terminate: mov sp, fp // restore stack pointer ldp fp, lr, [sp], 16 // restore registers from stack ret // return to os // Initialize the game // void initializeGame (*code, N, M, C, *guess) .type initializeGame, %function initializeGame: stp fp, lr, [sp, -16]! // save registers in stack stp x19, x20, [sp, -16]! // save registers in stack stp x21, x22, [sp, -16]! // save registers in stack stp x23, x24, [sp, -16]! // save registers in stack mov x19, x0 // save code pointer mov x22, x4 // save guess pointer sub x20, x3, 1 // save C - 1 mul w21, w1, w2 // get number of characters= n*m mov w23, w21 initLoop: mov w0, 0 // generate number between 0 mov w1, w20 // and C - 1 mov w2, 0 // positive bl randomNum // generate random number bl Color // convert to color strb w0, [x19], 1 // save in color array subs w21, w21, 1 // decrement number of chars to generate bne initLoop // repeat while not zero mov w21, w23 // get number of characters clrLoop: mov w0, 32 // save space strb w0, [x22], 1 // save in color array subs w21, w21, 1 // decrement number of chars bne clrLoop // repeat while not zero ldp x23, x24, [sp], 16 // restore registers from stack ldp x21, x22, [sp], 16 // restore registers from stack ldp x19, x20, [sp], 16 // restore registers from stack ldp fp, lr, [sp], 16 // restore registers from stack ret // return to calling function // Generate a random number between n and m, the number is negative if neg is 1 // int randomNum(n, m, neg) .type randomNum, %function randomNum: stp fp, lr, [sp, -16]! // save registers in stack stp x19, x20, [sp, -16]! // save registers in stack stp x21, x22, [sp, -16]! // save registers in stack mov x19, x0 // save n mov x20, x1 // save m mov x21, x2 // save neg bl rand // generate a random number sub w1, w20, w19 // calculate m-n add w1, w1, 1 // calculate m-n+1 udiv w2, w0, w1 // divide random number / (m-n+1) msub w3, w2, w1, w0 // calculate remainder add w0, w3, w19 // add n to get number between n and m (including n and m) cmp x21, 0 // check if need a negative beq rndReturn // if not negative, return neg w0, w0 // else, negate rndReturn: ldp x21, x22, [sp], 16 // restore registers from stack ldp x19, x20, [sp], 16 // restore registers from stack ldp fp, lr, [sp], 16 // restore registers from stack ret // return to calling function // Convert number to letter color // char Color(n) .type Color, %function Color: add w0, w0, 65 // convert 0... to 'A'... ret // return to calling function // Print code // void printCode(*code, n, m) .type printCode, %function printCode: stp fp, lr, [sp, -16]! // save registers in stack stp x19, x20, [sp, -16]! // save registers in stack mov x19, x0 // save code pointer mul w20, w1, w2 // get number of characters= n*m prLoop: ldrb w1, [x19], 1 // load char from color array ldr x0, =colorFmt // print color bl printf subs w20, w20, 1 // decrement number of chars to print bne prLoop // repeat while not zero ldp x19, x20, [sp], 16 // restore registers from stack ldp fp, lr, [sp], 16 // restore registers from stack ret // return to calling function // Print guess // void printGuess(*code, n, m, transcript) .type printGuess, %function printGuess: stp fp, lr, [sp, -16]! // save registers in stack stp x19, x20, [sp, -16]! // save registers in stack stp x21, x22, [sp, -16]! // save registers in stack mov fp, sp sub sp, sp, 256 // allocate buffer mov x19, x0 // save code pointer mov x21, x3 // save transcript mov x22, sp mul w20, w1, w2 // get number of characters= n*m prgLoop: ldrb w1, [x19], 1 // load char from color array //ldr x0, =colorFmt // print color //bl printf strb w1, [x22], 1 mov w1, 32 strb w1, [x22], 1 subs w20, w20, 1 // decrement number of chars to print bne prgLoop // repeat while not zero strb wzr, [x22], 1 mov x0, sp mov x1, x21 bl saveString // save in transcript mov sp, fp ldp x21, x22, [sp], 16 // restore registers from stack ldp x19, x20, [sp], 16 // restore registers from stack ldp fp, lr, [sp], 16 // restore registers from stack ret // return to calling function // Print hidden code // void printHidden(*code, n, m, *transcript) .type printHidden, %function printHidden: stp fp, lr, [sp, -16]! // save registers in stack stp x19, x20, [sp, -16]! // save registers in stack stp x21, x22, [sp, -16]! // save registers in stack mov fp, sp sub sp, sp, 256 // allocate buffer strb wzr, [sp] mov x19, x0 // save code pointer mov x21, x3 // save transcript mul w20, w1, w2 // get number of characters= n*m phLoop: mov x0, sp ldr x1, =hiddenFmt // print hidden char bl strcat subs w20, w20, 1 // decrement number of chars to print bne phLoop // repeat while not zero mov x0, sp ldr x1, =hintHeader // print hint header bl strcat mov x0, sp mov x1, x21 bl saveString // save in transcript mov sp, fp ldp x21, x22, [sp], 16 // restore registers from stack ldp x19, x20, [sp], 16 // restore registers from stack ldp fp, lr, [sp], 16 // restore registers from stack ret // return to calling function // Read the input from the user, returns 1 if no errors, -1 if user wants to exit // bool readInput(*input, N, M, C) .type readInput, %function readInput: stp fp, lr, [sp, -16]! // save registers in stack stp x19, x20, [sp, -16]! // save registers in stack stp x21, x22, [sp, -16]! // save registers in stack mov x19, x0 // save input array pointer mul w20, w1, w2 // get number of characters= n*m add w21, w3, 64 // last color char mov x22, 1 // no errors rdLoop: bl getchar // read character cmp w0, 10 // if enter beq readEnd cmp w0, '$' // if exit beq exitChar cmp w0, 32 // if space beq rdLoop // read again cmp w0, 'A' // if not a letter blt badChar // cmp w0, w21 // if not a letter bgt badChar // cmp w20, 0 // if we input all chars beq badChar strb w0, [x19], 1 // save in array sub w20, w20, 1 // decrement number of chars to save b rdLoop // read again exitChar: mov x22, -1 b rdLoop // repeat badChar: cmp x22, -1 // if exit beq rdLoop // ignore error mov x22, 0 // input error b rdLoop // repeat readEnd: cmp x22, -1 // if exit beq readRet // ignore errors cmp w20, 0 // else, check if all chars were given beq readRet // if so, return mov x22, 0 // else, error readRet: mov x0, x22 // return error status ldp x21, x22, [sp], 16 // restore registers from stack ldp x19, x20, [sp], 16 // restore registers from stack ldp fp, lr, [sp], 16 // restore registers from stack ret // return to calling function // display hints and returns B,W // int displayHints(guess, code, n, m, transcript) .type displayHints, %function displayHints: stp fp, lr, [sp, -16]! // save registers in stack stp x19, x20, [sp, -16]! // save registers in stack stp x21, x22, [sp, -16]! // save registers in stack stp x23, x24, [sp, -16]! // save registers in stack mov fp, sp mov x19, 0 // no exact matches mov x20, 0 // no approx matches mov x23, x4 // save transcript mul x4, x2, x3 // get number of characters= n*m sub sp, sp, x4 // allocate first array mov x21, sp // point to stack sub sp, sp, x4 // allocate second array mov x22, sp // point to stack mov x5, 0 // index = 0 comp1: ldrb w6, [x0, x5] // load guess character ldrb w7, [x1, x5] // load code character cmp w6, w7 // compare chars bne notEq add x19, x19, 1 // increment exact matches mov w6, 1 strb w6, [x21, x5] // save guess character used strb w6, [x22, x5] // save code character used b nxtComp1 notEq: strb wzr, [x21, x5] // save guess character not used strb wzr, [x22, x5] // save code character not used nxtComp1: add x5, x5, 1 // increment index cmp x5, x4 // if not end blt comp1 // keep comparing mov x5, 0 // index guess = 0 comp2: ldrb w6, [x21, x5] // check if guess character was used cmp w6, 0 // if used, bne nxtComp2 // try next ldrb w6, [x0, x5] // load guess character mov x7, 0 // index code = 0 comp3: ldrb w9, [x22, x7] // check if code character was used cmp w9, 0 // if used, bne nxtComp3 // try next ldrb w9, [x1, x7] // load code character cmp w6, w9 // compare chars bne nxtComp3 // if not equal, try next code char add x20, x20, 1 // increment approx matches mov w6, 1 strb w6, [x21, x5] // save guess character used strb w6, [x22, x7] // save code character used b nxtComp2 nxtComp3: add x7, x7, 1 // increment index cmp x7, x4 // if not end bne comp3 // keep comparing nxtComp2: add x5, x5, 1 // increment index cmp x5, x4 // if not end bne comp2 // keep comparing endit: add sp, sp, x4, lsl 1 // remove allocated space in stack sub sp, sp, 16 mov x0, sp ldr x1, =hintBW // load hint b w format mov w2, w19 // load exact matches mov w3, w20 // load approximate matches bl sprintf // print result mov x0, sp mov x1, x23 bl saveString // save hints add sp, sp, 16 mov x0, x19 // return exact matches mov x1, x20 // return approximate matches ldp x23, x24, [sp], 16 // restore registers from stack ldp x21, x22, [sp], 16 // restore registers from stack ldp x19, x20, [sp], 16 // restore registers from stack ldp fp, lr, [sp], 16 // restore registers from stack ret // return to calling function // Calculate overall score // double calculateScore(S, R, T) .type calculateScore, %function calculateScore: ucvtf d1, x0 // convert tries to float fdiv d0, d0, d1 // S/R mov x2, 1000 // multiply remaining time T * 1000 mul x1, x1, x2 ucvtf d2, x1 // convert remaining seconds to float fmul d0, d0, d2 // (S/R)*T*1000 mov x0, 100 // load 100 ucvtf d1, x0 // counvert to float fmul d0, d0, d1 // round to 100 frinta d0, d0 fdiv d0, d0, d1 ret // return to calling function // Exit the game // void exitGame(*code, *game) .type exitGame, %function exitGame: stp fp, lr, [sp, -16]! // save registers in stack stp x19, x20, [sp, -16]! // save registers in stack mov x19, x1 bl free // free allocated space for code mov x0, x19 // free allocated space for guess bl free ldp x19, x20, [sp], 16 // restore registers from stack ldp fp, lr, [sp], 16 // restore registers from stack mov x0, xzr // exit (0) bl exit // Log the score // void logScore(name, score, T) .type logScore, %function logScore: stp fp, lr, [sp, -16]! // save registers in stack stp x19, x20, [sp, -16]! // save registers in stack stp d8, d9, [sp, -16]! // save registers in stack sub sp, sp, 32 mov x19, x0 // save name pointer fmov d8, d0 // save score fmov d9, d1 // save T ldr x0, =logFilename // open file ldr x1, =logWMode // mode to append bl fopen mov x20, x0 // save file pointer mov x0, sp // clear buffer mov x1, xzr mov x2, 16 bl memset mov x0, sp mov x1, x19 // copy name mov x2, 16 bl strncpy mov x0, sp // save name mov x1, 1 mov x2, 16 mov x3, x20 bl fwrite stp d8, d9, [sp, -16]! // save registers in stack mov x0, sp // save score mov x1, 1 mov x2, 8 mov x3, x20 bl fwrite add x0, sp, 8 // save time mov x1, 1 mov x2, 8 mov x3, x20 bl fwrite ldp d8, d9, [sp], 16 // restore registers from stack mov x0, x20 // close file bl fclose add sp, sp, 32 ldp d8, d9, [sp], 16 // restore registers from stack ldp x19, x20, [sp], 16 // restore registers from stack ldp fp, lr, [sp], 16 // restore registers from stack ret // Load score file and returns array and array size // scores* loadScores() .type loadScores, %function loadScores: stp fp, lr, [sp, -16]! // save registers in stack stp x19, x20, [sp, -16]! // save registers in stack stp x21, x22, [sp, -16]! // save registers in stack ldr x0, =logFilename // open file ldr x1, =logRMode // mode to read bl fopen mov x19, x0 // save file pointer mov x1, 0 // move to end of file mov x2, 2 bl fseek mov x0, x19 // get file size bl ftell uxtw x0, w0 mov x20, x0 // save size mov x0, x20 bl malloc // allocate space for whole file mov x21, x0 mov x0, x19 // move to start of file mov x1, xzr mov x2, xzr bl fseek mov x0, x21 // load all scores mov x1, 1 mov x2, x20 mov x3, x19 bl fread mov x0, x19 // close the file bl fclose mov x0, x21 // return array lsr x1, x20, 5 // return number of scores ldp x21, x22, [sp], 16 // restore registers from stack ldp x19, x20, [sp], 16 // restore registers from stack ldp fp, lr, [sp], 16 // restore registers from stack ret // Display the top n scores on score file .type displayTop, %function displayTop: stp fp, lr, [sp, -16]! // save registers in stack stp x19, x20, [sp, -16]! // save registers in stack stp x21, x22, [sp, -16]! // save registers in stack mov x19, x0 // save n ldr x0, =topScoresMsg // print top scores message mov x1, x19 bl printf ldr x0, =scoresHeader // print header bl printf bl loadScores // load all scores mov x20, x0 // save array mov x21, x1 // save size mov x22, x0 mov x0, x20 mov x1, x21 mov x2, 1 // sort inverted (top at bottom) bl sortScores // sort scores printTop: ldr d0, [x20, 24] // load time bl isinf // check if it's infinite cmp w0, 0 // if not infinite beq prScore // print score ldr x0, =logInf mov x1, x20 // print name ldr d0, [x20, 16] // load score ldr d1, [x20, 24] // load time bl printf // print entry b nextTop prScore: ldr d0, [x20, 24] // load time fcvtas x1, d0 // convert to integer mov x0, 60 // 60 seconds per minute udiv x2, x1, x0 // t/60 msub x3, x2, x0, x1 // calculate remainder ldr x0, =logFmt mov x1, x20 // print name ldr d0, [x20, 16] // load score bl printf // print entry nextTop: add x20, x20, 32 // advance to next entry subs x19, x19, 1 // decrement n beq endTop subs x21, x21, 1 // decrement size bne printTop endTop: mov x0, x22 // free array bl free ldp x21, x22, [sp], 16 // restore registers from stack ldp x19, x20, [sp], 16 // restore registers from stack ldp fp, lr, [sp], 16 // restore registers from stack ret // Display the bottom n scores on score file .type displayBottom, %function displayBottom: stp fp, lr, [sp, -16]! // save registers in stack stp x19, x20, [sp, -16]! // save registers in stack stp x21, x22, [sp, -16]! // save registers in stack mov x19, x0 // save n ldr x0, =botScoresMsg mov x1, x19 bl printf ldr x0, =scoresHeader // print header bl printf bl loadScores // load all scores mov x20, x0 // save array mov x21, x1 // save size mov x22, x0 mov x0, x20 mov x1, x21 mov x2, 0 // sort normally (smallest at bottom) bl sortScores // sort scores printBot: ldr d0, [x20, 24] // load time bl isinf // check if it's infinite cmp w0, 0 // if infinite bne nextBot // go to next value ldr d0, [x20, 24] // load time fcvtas x1, d0 // convert to integer mov x0, 60 // 60 seconds per minute udiv x2, x1, x0 // t/60 msub x3, x2, x0, x1 // calculate remainder ldr x0, =logFmt mov x1, x20 // print name ldr d0, [x20, 16] // load score bl printf // print entry subs x19, x19, 1 // decrement n beq endBot nextBot: add x20, x20, 32 // advance to next entry subs x21, x21, 1 // decrement size bne printBot endBot: mov x0, x22 // free array bl free ldp x21, x22, [sp], 16 // restore registers from stack ldp x19, x20, [sp], 16 // restore registers from stack ldp fp, lr, [sp], 16 // restore registers from stack ret // Sort the score array in the given direction // void sortScores(*scores, N, direction) .type sortScores, %function sortScores: stp fp, lr, [sp, -16]! // save registers in stack sub x1, x1, 1 // decrement to N-1 mov x7, 0 // i = 0 for1: cmp x7, x1 // for (i = 0; i < N - 1; i++) beq endfor1 add x5, x0, x7, lsl 5 // array entry i ldr d0, [x5, 16] // load array[i].score mov x3, x7 // min = i add x4, x7, 1 // j = i + 1; for2: cmp x4, x1 // for (j = i + 1; j <= N - 1; j++) bgt endfor2 add x6, x0, x4, lsl 5 // array entry j ldr d1, [x6, 16] // load array[j].score cmp x2, 0 // if normal direction bne invert fcmp d1, d0 // if (score j < score min) bge nextj fmov d0, d1 // set score as new minimum mov x3, x4 // save j as min b nextj invert: fcmp d1, d0 // if (score j > score min) ble nextj fmov d0, d1 // set score as new maximum mov x3, x4 // save j as max nextj: add x4, x4, 1 // j++ b for2 // repeat for endfor2: add x5, x0, x7, lsl 5 // array entry i add x6, x0, x3, lsl 5 // array entry min ldr x3, [x5] // load array[i].name ldr x4, [x6] // load array[min].name str x4, [x5] // swap str x3, [x6] ldr x3, [x5, 8] // load array[i].name ldr x4, [x6, 8] // load array[min].name str x4, [x5, 8] // swap str x3, [x6, 8] ldr x3, [x5, 16] // load array[i].score ldr x4, [x6, 16] // load array[min].score str x4, [x5, 16] // swap str x3, [x6, 16] ldr x3, [x5, 24] // load array[i].time ldr x4, [x6, 24] // load array[min].time str x4, [x5, 24] // swap str x3, [x6, 24] add x7, x7, 1 // i++ b for1 // repeat for endfor1: ldp fp, lr, [sp], 16 // restore registers from stack ret // Read N from user .type readN, %function readN: stp fp, lr, [sp, -16]! // save registers in stack sub sp, sp, 16 // allocate space in stack ldr x0, =promptN // prompt for n bl printf ldr x0, =intFmt // read an integer mov x1, sp bl scanf lN: bl getchar // read until enter is pressed cmp w0, 10 bne lN ldr w0, [sp] // get read value uxtw x0, w0 // extend to x0 add sp, sp, 16 // remove allocated space ldp fp, lr, [sp], 16 // restore registers from stack ret // return to caller // Reads a character from input // char readChar() .type readChar, %function readChar: stp fp, lr, [sp, -16]! // save registers in stack stp x19, x20, [sp, -16]! // save registers in stack bl getchar // read input mov w19, w0 // save char l0: cmp w0, 10 // if enter, end input beq rdChrEnd bl getchar // read until enter is pressed b l0 rdChrEnd: mov w0, w19 // return read char uxtb x0, w0 // extend to x0 ldp x19, x20, [sp], 16 // restore registers from stack ldp fp, lr, [sp], 16 // restore registers from stack ret // Show the scores depending on user input // void showScores() .type showScores, %function showScores: stp fp, lr, [sp, -16]! // save registers in stack ldr x0, =showTopMsg // ask if top/bottom should be printed bl printf bl readChar // read input cmp w0, 'B' // if bottom beq showBottom // print bottom cmp w0, 'b' // if bottom beq showBottom // print bottom cmp w0, 'T' // if top beq showTop // print top cmp w0, 't' // if top beq showTop // print top b showEnd // else, end showBottom: bl readN // read N value bl displayBottom // displayBotton(n) b showEnd showTop: bl readN // read N value bl displayTop // displayTop(n) showEnd: ldp fp, lr, [sp], 16 // restore registers from stack ret // Save transcript file // void transcriptGame(*filename, *transcript) .type transcriptGame, %function transcriptGame: stp fp, lr, [sp, -16]! // save registers in stack stp x19, x20, [sp, -16]! // save registers in stack mov x19, x1 // save transcript pointer ldr x1, =transWMode // create transcript file bl fopen mov x20, x0 // save file pointer ldr x19, [x19] // load transcript head saveLoop: cmp x19, 0 // if end of transcript beq endTrans // end loop mov x0, x20 // load file pointer ldr x1, [x19] // pass string pointer bl fprintf // print to file ldr x19, [x19, 8] // load next transcript b saveLoop endTrans: mov x0, x20 // close file bl fclose ldp x19, x20, [sp], 16 // restore registers from stack ldp fp, lr, [sp], 16 // restore registers from stack ret // Free transcript // void freeTranscript(*transcript) .type freeTranscript, %function freeTranscript: stp fp, lr, [sp, -16]! // save registers in stack stp x19, x20, [sp, -16]! // save registers in stack ldr x20, [x0] // load transcript head freeLoop: cmp x20, 0 // if end of transcript beq endFree // end loop ldr x0, [x20] // pass string pointer bl free // free string ldr x19, [x20, 8] // load next transcript mov x0, x20 // pass node pointer bl free // free node mov x20, x19 // use next node for iteration b freeLoop endFree: ldp x19, x20, [sp], 16 // restore registers from stack ldp fp, lr, [sp], 16 // restore registers from stack ret // Insert string to end of transcript and prints it: // void saveString(*string, *transcript) saveString: stp fp, lr, [sp, -16]! // save registers in stack stp x19, x20, [sp, -16]! // save registers in stack stp x21, x22, [sp, -16]! // save registers in stack mov x19, x0 // save string pointer mov x20, x1 // save transcript pointer mov x0, x19 // print string bl printf mov x0, 16 // node size bl malloc // allocate node mov x21, x0 // save node pointer mov x0, x19 // pass string bl strlen // get length add x0, x0, 1 bl malloc // allocate string mov x22, x0 // save pointer mov x0, x22 // copy string mov x1, x19 bl strcpy str x22, [x21] // save string pointer in node str xzr, [x21, 8] // save next as null ldr x0, [x20] // load transcript head cmp x0, 0 // if empty list bne findLast // if not, insert at last str x21, [x20] // save new node as head b insertEnd findLast: ldr x1, [x0, 8] // load next transcript cmp x1, 0 // if null beq saveNode // end loop mov x0, x1 // go to next b findLast saveNode: str x21, [x0, 8] // save new node as last insertEnd: ldp x21, x22, [sp], 16 // restore registers from stack ldp x19, x20, [sp], 16 // restore registers from stack ldp fp, lr, [sp], 16 // restore registers from stack ret define(code,x19)

Similar Samples

Discover expertly crafted programming assignment solutions at ProgrammingHomeworkHelp.com. Our samples showcase top-quality work, demonstrating our commitment to helping students excel. Browse through various projects and see firsthand the level of precision and excellence you can expect from our services.