├── declword.s ├── declword4.s ├── declblob.s ├── declstring.s ├── declstrword.s ├── decleq2.s ├── declstruct.s ├── return123.s ├── invert.s ├── declequ.s ├── odd.s ├── mask.s ├── abs.s ├── findcaller.s ├── findme.s ├── load0.s ├── load1.s ├── findstack.s ├── pow2.s ├── mask2.s ├── func_pack3.s ├── load2.s ├── loaddecl3.s ├── bswap.s ├── fib1.s ├── shiftl.s ├── shiftu.s ├── loaddecl2.s ├── shifts.s ├── return.s ├── loaddecl1.s ├── bcd2.s ├── add.s ├── add64.s ├── bits1.s ├── hex1.s ├── findlabel.s ├── signext.s ├── strlen.s ├── zeroext.s ├── bits2.s ├── findfunction.s ├── saturate.s ├── load.s ├── swap.s ├── callparam.s ├── array_inc.s ├── linklist_del.s ├── load_align.s ├── chrcpy.s ├── arraysum.s ├── random.s ├── popcount.s ├── hailstone.s ├── memcpy.s ├── README.md ├── maxu.s ├── decstr1.s ├── strtolower.s ├── maxs8.s ├── mins.s ├── saturate2.s ├── peak.s ├── extend.s ├── increment_align.s ├── subarraysum.s ├── arrayinsert.s ├── ifelse1.s └── sum_args20.s /declword.s: -------------------------------------------------------------------------------- 1 | # Insert declarations here 2 | One: .word 1 3 | Two: .word 2 4 | -------------------------------------------------------------------------------- /declword4.s: -------------------------------------------------------------------------------- 1 | # Insert declarations here 2 | .hword 'y', 'z' 3 | A: .hword 0x61, 98 4 | -------------------------------------------------------------------------------- /declblob.s: -------------------------------------------------------------------------------- 1 | # Insert declarations here 2 | Blob: .word 0x04030201, 0x08070605, 0x0c0b0a09 3 | -------------------------------------------------------------------------------- /declstring.s: -------------------------------------------------------------------------------- 1 | // Insert declarations here 2 | .data 3 | Hello: .string "This is a string" 4 | -------------------------------------------------------------------------------- /declstrword.s: -------------------------------------------------------------------------------- 1 | # Insert declarations here 2 | STUFF: .string "Hi" 3 | .align 1 4 | .word 0x1234 5 | -------------------------------------------------------------------------------- /decleq2.s: -------------------------------------------------------------------------------- 1 | // Insert declarations here 2 | Nums: .word STARTVAL, STARTVAL+1, STARTVAL+2, STARTVAL+3 3 | 4 | -------------------------------------------------------------------------------- /declstruct.s: -------------------------------------------------------------------------------- 1 | # Insert declarations here 2 | List: .string "M5S3G4" 3 | .hword 416 4 | .string "V6T1Z4" 5 | .hword 604 6 | .string "K7L3N6" 7 | .hword 613 8 | -------------------------------------------------------------------------------- /return123.s: -------------------------------------------------------------------------------- 1 | .global _start 2 | _start: 3 | bl func 4 | 1: b 1b // done 5 | 6 | .global func 7 | func: 8 | MOV R0, #123 9 | BX LR 10 | 11 | -------------------------------------------------------------------------------- /invert.s: -------------------------------------------------------------------------------- 1 | .global _start 2 | _start: 3 | mov r0, #1 4 | bl invert 5 | 1: b 1b // Done 6 | 7 | .global invert 8 | invert: 9 | MVN R0, R0 10 | BX LR 11 | -------------------------------------------------------------------------------- /declequ.s: -------------------------------------------------------------------------------- 1 | // Insert declarations here 2 | .equ LEDS, 0xFF200000 3 | .global get_led 4 | // A function that returns the value of LEDS 5 | get_led: 6 | LDR R0, =LEDS 7 | BX LR 8 | -------------------------------------------------------------------------------- /odd.s: -------------------------------------------------------------------------------- 1 | .global _start 2 | _start: 3 | mov r0, #1 4 | bl odd 5 | 1: b 1b // Done 6 | 7 | .global odd 8 | odd: 9 | BIC R0, R0, #0xFFFFFFFE 10 | BX LR 11 | -------------------------------------------------------------------------------- /mask.s: -------------------------------------------------------------------------------- 1 | .global _start 2 | _start: 3 | ldr r0, =4 4 | bl mask 5 | 1: b 1b // Done 6 | 7 | mask: 8 | MOV R1, #1 9 | LSL R1, R0 10 | SUB R0, R1, #1 11 | BX LR 12 | -------------------------------------------------------------------------------- /abs.s: -------------------------------------------------------------------------------- 1 | .global _start 2 | _start: 3 | mov r0, #10 4 | bl abs 5 | 1: b 1b // Done 6 | 7 | .global abs 8 | abs: 9 | CMP R0, #0 10 | NEGLT R0, R0 11 | BX LR 12 | -------------------------------------------------------------------------------- /findcaller.s: -------------------------------------------------------------------------------- 1 | // Some testing code 2 | .global _start 3 | _start: 4 | bl where 5 | 1: b 1b // done 6 | 7 | // Your function starts here: 8 | where: 9 | SUB R0, LR, #4 10 | BX LR 11 | -------------------------------------------------------------------------------- /findme.s: -------------------------------------------------------------------------------- 1 | // Some testing code 2 | .global _start 3 | _start: 4 | bl where 5 | 1: b 1b // done 6 | 7 | # Your function starts here: 8 | where: 9 | LDR R0, =where 10 | BX LR 11 | 12 | -------------------------------------------------------------------------------- /load0.s: -------------------------------------------------------------------------------- 1 | //Data: .word 0x123 // Uncomment for debugging 2 | .global _start 3 | _start: 4 | bl load 5 | 1: b 1b // Done 6 | load: 7 | LDR R1, =Data 8 | LDR R0, [R1] 9 | BX LR 10 | -------------------------------------------------------------------------------- /load1.s: -------------------------------------------------------------------------------- 1 | Data: .word 0x123 2 | .global _start 3 | _start: 4 | ldr r0, =Data 5 | bl load 6 | 1: b 1b // Done 7 | 8 | // Dereference a pointer 9 | load: 10 | LDR R0, [R0] 11 | BX LR 12 | -------------------------------------------------------------------------------- /findstack.s: -------------------------------------------------------------------------------- 1 | // Some testing code 2 | .global _start 3 | _start: 4 | ldr sp, =0x4000000 5 | bl where 6 | 7 | 1: b 1b // done 8 | 9 | // Your function starts here: 10 | where: 11 | MOV R0, SP 12 | BX LR 13 | 14 | -------------------------------------------------------------------------------- /pow2.s: -------------------------------------------------------------------------------- 1 | .global _start 2 | _start: 3 | ldr r0, =4 4 | bl pow2 5 | 1: b 1b // Done 6 | 7 | pow2: 8 | SUB R1, R0, #1 9 | AND R1, R0 10 | CMP R1, #0 11 | MOVEQ R0, #1 12 | MOVNE R0, #0 13 | BX LR 14 | 15 | -------------------------------------------------------------------------------- /mask2.s: -------------------------------------------------------------------------------- 1 | .global _start 2 | _start: 3 | ldr r0, =4 4 | ldr r1, =2 5 | bl mask 6 | 1: b 1b // Done 7 | 8 | mask: 9 | SUB R0, R1 10 | MOV R2, #1 11 | LSL R2, R0 12 | SUB R0, R2, #1 13 | LSL R0, R1 14 | BX LR 15 | -------------------------------------------------------------------------------- /func_pack3.s: -------------------------------------------------------------------------------- 1 | .global _start 2 | _start: 3 | ldr r0, =0x20000 4 | mov r1, #3 5 | mov r2, #4 6 | mov r3, #5 7 | bl pack3 8 | 1: b 1b // done 9 | 10 | .global pack3 11 | pack3: 12 | STM R0, {R1, R2, R3} 13 | BX LR 14 | -------------------------------------------------------------------------------- /load2.s: -------------------------------------------------------------------------------- 1 | Data: .word 0x123, 0x124, 0x125 2 | .global _start 3 | _start: 4 | ldr r0, =Data 5 | ldr r1, =1 6 | bl load 7 | 1: b 1b // Done 8 | 9 | // Dereference a pointer 10 | load: 11 | LDR R0, [R0, R1, LSL #2] 12 | BX LR 13 | -------------------------------------------------------------------------------- /loaddecl3.s: -------------------------------------------------------------------------------- 1 | // Declare something 2 | .data 3 | Data: .word A 4 | A: .word B 5 | B: .word 0x12345 6 | 7 | .text 8 | .global _start 9 | _start: 10 | ldr r0, =Data 11 | ldr r1, [r0] 12 | ldr r2, [r1] 13 | ldr r3, [r2] 14 | 1: b 1b // Done 15 | -------------------------------------------------------------------------------- /bswap.s: -------------------------------------------------------------------------------- 1 | // A test case to test your function with 2 | .global _start 3 | _start: 4 | ldr r0, =0x11223344 5 | bl bswap 6 | b _start // End of testing code 7 | 8 | // Byte swap 9 | bswap: 10 | REV R0, R0 11 | BX LR 12 | 13 | -------------------------------------------------------------------------------- /fib1.s: -------------------------------------------------------------------------------- 1 | MEM: .word 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393, 196418, 317811, 514229, 832040, 1346269, 2178309 2 | fib: 3 | LDR R1, =MEM 4 | LDR R0, [R1, R0, LSL #2] 5 | BX LR 6 | -------------------------------------------------------------------------------- /shiftl.s: -------------------------------------------------------------------------------- 1 | // A test case to test your function with 2 | 3 | .global _start 4 | _start: 5 | ldr r0, =0x1234 6 | bl shift 7 | b _start // End of testing code 8 | 9 | // Convert one S16 to S32 format 10 | shift: 11 | LSL R0, #16 12 | BX LR 13 | 14 | -------------------------------------------------------------------------------- /shiftu.s: -------------------------------------------------------------------------------- 1 | // A test case to test your function with 2 | 3 | .global _start 4 | _start: 5 | ldr r0, =0x12345678 6 | bl shift 7 | b _start // End of testing code 8 | 9 | // Convert one U32 sample to U8 format 10 | shift: 11 | LSR R0, #24 12 | BX LR 13 | -------------------------------------------------------------------------------- /loaddecl2.s: -------------------------------------------------------------------------------- 1 | // Declare something 2 | .data 3 | Data: .word 4, 4, 0x1234 4 | 5 | .text 6 | .global _start 7 | _start: 8 | ldr r0, =Data 9 | ldr r1, [r0] 10 | add r0, r0, r1 11 | ldr r1, [r0] 12 | add r0, r0, r1 13 | ldr r2, [r0] 14 | 1: b 1b // Done 15 | 16 | 17 | -------------------------------------------------------------------------------- /shifts.s: -------------------------------------------------------------------------------- 1 | // A test case to test your function with 2 | 3 | .global _start 4 | _start: 5 | ldr r0, =0x40000 6 | bl shift 7 | b _start // End of testing code 8 | 9 | // Return 1/4 amplitude for a S32 sample 10 | shift: 11 | ASR R0, #2 // log2(4) = 2 12 | BX LR 13 | -------------------------------------------------------------------------------- /return.s: -------------------------------------------------------------------------------- 1 | .global _start 2 | _start: 3 | // This is for testing your function 4 | bl func // Call your function 5 | // Your function should return here. 6 | 1: b 1b // Infinite loop to stop program after testing 7 | 8 | .global func 9 | func: 10 | BX LR 11 | -------------------------------------------------------------------------------- /loaddecl1.s: -------------------------------------------------------------------------------- 1 | // Declare something 2 | .data 3 | Data: 4 | .word 0, 0x1234 5 | .hword 0x5678 6 | .align 1 7 | .byte 0, 0x90 8 | 9 | .text 10 | .global _start 11 | _start: 12 | ldr r0, =Data 13 | ldr r1, [r0, #4] 14 | ldrh r2, [r0, #8] 15 | ldrb r3, [r0, #11] 16 | 1: b 1b // Done 17 | 18 | 19 | -------------------------------------------------------------------------------- /bcd2.s: -------------------------------------------------------------------------------- 1 | // A test case to test your function with 2 | .global _start 3 | _start: 4 | ldr r0, =10 // First parameter is always in r0 5 | bl bcd 6 | b _start // End of testing code 7 | 8 | // Convert a number to BCD representation 9 | bcd: 10 | CMP R0, #0x9 11 | ADDGT R0, #6 12 | BX LR 13 | 14 | -------------------------------------------------------------------------------- /add.s: -------------------------------------------------------------------------------- 1 | .global _start 2 | _start: 3 | mov r0, #1 // First function parameter is always passed through r0. 4 | mov r1, #1 // Second function parameter is always passed through r1. 5 | bl add // Return value is always in r0. 6 | 1: b 1b // Done 7 | 8 | .global add 9 | add: 10 | ADD R0, R0, R1 11 | BX LR 12 | -------------------------------------------------------------------------------- /add64.s: -------------------------------------------------------------------------------- 1 | .global _start 2 | _start: 3 | mov r0, #1 // Lower 32 bits of a 4 | mov r1, #0 // Upper 32 bits of a 5 | mov r2, #1 // Lower 32 bits of b 6 | mov r3, #0 // Upper 32-bits of b 7 | bl add64 8 | 1: b 1b // Done 9 | 10 | .global add64 11 | add64: 12 | ADDS R0, R2 13 | ADC R1, R3 14 | BX LR 15 | -------------------------------------------------------------------------------- /bits1.s: -------------------------------------------------------------------------------- 1 | // A test case to test your function with 2 | .global _start 3 | _start: 4 | ldr r0, =0x1000 5 | bl bits 6 | b _start // End of testing code 7 | 8 | // Return minimum number of bits to represent first parameter 9 | bits: 10 | CLZ R0, R0 11 | RSB R0, R0, #32 // 32-(leading zeros) 12 | BX LR 13 | 14 | -------------------------------------------------------------------------------- /hex1.s: -------------------------------------------------------------------------------- 1 | // A test case to test your function with 2 | .global _start 3 | _start: 4 | ldr r0, =0xa // First parameter is always in r0 5 | bl hex1 6 | b _start // End of testing code 7 | 8 | // Print one hex digit 9 | hex1: 10 | CMP R0, #0xa 11 | ADDLT R0, #0x30 12 | ADDGE R0, #0x57 13 | BX LR 14 | 15 | -------------------------------------------------------------------------------- /findlabel.s: -------------------------------------------------------------------------------- 1 | // Some testing code 2 | // Make sure to submit without "Waldo" defined in your code, or you will get a "multiple definition" error. 3 | // Waldo: .string "Where's Waldo??" 4 | 5 | .global _start 6 | _start: 7 | bl where 8 | 1: b 1b // done 9 | 10 | // Your function starts here: 11 | where: 12 | LDR R0, =Waldo 13 | BX LR 14 | -------------------------------------------------------------------------------- /signext.s: -------------------------------------------------------------------------------- 1 | // A test case to test your function with 2 | .global _start 3 | _start: 4 | mov r0, #0xf0 // First parameter is always in r0 5 | bl signext 6 | b _start // End of testing code 7 | 8 | // A function to sign extend. Only this part will be tested. 9 | signext: 10 | LSL R0, #24 11 | ASR R0, #24 12 | BX LR 13 | -------------------------------------------------------------------------------- /strlen.s: -------------------------------------------------------------------------------- 1 | .data 2 | MyString: .string "Hello World" 3 | 4 | .text 5 | .global _start 6 | _start: 7 | ldr r0, =MyString 8 | bl strlen 9 | 1: b 1b 10 | 11 | .global strlen 12 | strlen: 13 | MOV R1, #0 14 | LOOP: 15 | LDRB R2, [R0, R1] 16 | CMP R2, #0 17 | ADDNE R1, #1 18 | BNE LOOP 19 | MOV R0, R1 20 | BX LR 21 | -------------------------------------------------------------------------------- /zeroext.s: -------------------------------------------------------------------------------- 1 | // A test case to test your function with 2 | .global _start 3 | _start: 4 | ldr r0, =0xf0 // First parameter is always in r0 5 | bl zeroext 6 | b _start // End of testing code 7 | 8 | // A function to zero extend. Only this part will be tested. 9 | zeroext: 10 | LSL R0, #24 11 | LSR R0, #24 12 | BX LR 13 | -------------------------------------------------------------------------------- /bits2.s: -------------------------------------------------------------------------------- 1 | // A test case to test your function with 2 | .global _start 3 | _start: 4 | ldr r0, =0x1000 5 | bl bits 6 | b _start // End of testing code 7 | 8 | // Return minimum number of bits to represent first parameter 9 | bits: 10 | CMP R0, #0 11 | MVNLT R0, R0 12 | CLZ R0, R0 13 | RSB R0, R0, #33 14 | BX LR 15 | -------------------------------------------------------------------------------- /findfunction.s: -------------------------------------------------------------------------------- 1 | // Some testing code 2 | // Make sure to submit without "MyFunc" defined in your code, or you will get a "multiple definition" error. 3 | // MyFunc: ret 4 | 5 | .global _start 6 | _start: 7 | bl get_opcode 8 | 1: b 1b // done 9 | 10 | // Your function starts here: 11 | get_opcode: 12 | LDR R0, =MyFunc 13 | LDR R0, [R0] 14 | BX LR 15 | 16 | -------------------------------------------------------------------------------- /saturate.s: -------------------------------------------------------------------------------- 1 | // A test case to test your function with 2 | .global _start 3 | _start: 4 | ldr r0, =0x12345 // First parameter is always in r0 5 | bl saturate 6 | b _start // End of testing code 7 | 8 | // Convert unsigned 32 bit to 16 bit, with saturation 9 | saturate: 10 | LDR R1, =0x0000FFFF 11 | CMP R0, R1 12 | MOVHS R0, R1 13 | BX LR 14 | -------------------------------------------------------------------------------- /load.s: -------------------------------------------------------------------------------- 1 | .global _start 2 | _start: 3 | ldr r0, =0x345678 4 | ldr r1, =123 5 | str r1, [r0] 6 | movw r0, #0xbad // This function has no parameters. 7 | movw r1, #0xbad // So destroy the value here so you won't be tempted to use it. 8 | bl load 9 | 1: b 1b // Done 10 | 11 | .global load 12 | load: 13 | LDR R1, =0x345678 14 | LDR R0, [R1] 15 | BX LR 16 | -------------------------------------------------------------------------------- /swap.s: -------------------------------------------------------------------------------- 1 | Data: .word 0x123, 0x124, 0x125 2 | .global _start 3 | _start: 4 | ldr r0, =Data 5 | ldr r1, =0 6 | ldr r2, =2 7 | bl swap 8 | 1: b 1b // Done 9 | 10 | // Swap two array elements 11 | swap: 12 | PUSH {R4} 13 | LDR R3, [R0, R1, LSL #2] 14 | LDR R4, [R0, R2, LSL #2] 15 | STR R3, [R0, R2, LSL #2] 16 | STR R4, [R0, R1, LSL #2] 17 | POP {R4} 18 | BX LR 19 | -------------------------------------------------------------------------------- /callparam.s: -------------------------------------------------------------------------------- 1 | .global _start 2 | _start: 3 | bl call1234 4 | 1: b 1b 5 | 6 | //secret: // For debugging, uncomment this label 7 | // Don't submit with this label though, or you will get a duplicate label error. 8 | mov r0, #1 9 | bx lr 10 | 11 | .global call1234 12 | call1234: 13 | MOV R0, #1 14 | MOV R1, #2 15 | MOV R2, #3 16 | MOV R3, #4 17 | B secret 18 | BX LR 19 | 20 | -------------------------------------------------------------------------------- /array_inc.s: -------------------------------------------------------------------------------- 1 | .data 2 | Array: .word 1, 2, 3, 4 3 | 4 | .text 5 | .global _start 6 | _start: 7 | ldr r0, =Array 8 | mov r1, #4 9 | bl array_inc 10 | 1: b 1b // Done 11 | 12 | .global array_inc 13 | array_inc: 14 | SUB R1, #1 15 | LOOP: 16 | CMP R1, #0 17 | BXLT LR 18 | LDR R2, [R0, R1, LSL #2] 19 | ADD R2, #1 20 | STR R2, [R0, R1, LSL #2] 21 | SUB R1, #1 22 | B LOOP 23 | 24 | -------------------------------------------------------------------------------- /linklist_del.s: -------------------------------------------------------------------------------- 1 | .data 2 | A: .word B 3 | D: .word 0 4 | C: .word D 5 | B: .word C 6 | .text 7 | .global _start 8 | _start: 9 | ldr r0, =A 10 | bl listdel 11 | 1: b 1b // done 12 | 13 | .global listdel 14 | listdel: 15 | CMP R0, #0 16 | BXEQ LR 17 | LDR R1, [R0] 18 | CMP R1, #0 19 | MOVEQ R0, #0 20 | BXEQ LR 21 | LDR R2, [R1] 22 | STR R2, [R0] 23 | MOV R0, R1 24 | BX LR 25 | -------------------------------------------------------------------------------- /load_align.s: -------------------------------------------------------------------------------- 1 | .data 2 | Pointer: .word 1234 3 | .text 4 | .global _start 5 | _start: 6 | ldr r0, =Pointer 7 | bl load 8 | 1: b 1b // Done 9 | 10 | .global load 11 | load: 12 | LDRB R1, [R0, #3] 13 | LDRB R2, [R0, #2] 14 | LSL R1, #8 15 | ADD R1, R2 16 | LDRB R2, [R0, #1] 17 | LSL R1, #8 18 | ADD R1, R2 19 | LDRB R2, [R0] 20 | LSL R1, #8 21 | ADD R0, R1, R2 22 | BX LR 23 | -------------------------------------------------------------------------------- /chrcpy.s: -------------------------------------------------------------------------------- 1 | .data 2 | Src: .string "hello" 3 | .align 2 // Insert padding so it's easier to read. 4 | Dst: .string "bye" 5 | 6 | .text 7 | .global _start 8 | _start: 9 | ldr r0, =Src 10 | ldr r1, =1 11 | ldr r2, =Dst 12 | ldr r3, =1 13 | bl chrcpy 14 | 1: b 1b // Done 15 | 16 | // Copy a character from one string to another 17 | chrcpy: 18 | LDRB R1, [R0, R1] 19 | STRB R1, [R2, R3] 20 | BX LR 21 | -------------------------------------------------------------------------------- /arraysum.s: -------------------------------------------------------------------------------- 1 | // A test case to test your function with 2 | Array: .word 1, 2, 3 3 | 4 | .global _start 5 | _start: 6 | ldr r0, =Array 7 | ldr r1, =3 8 | bl arraysum 9 | b _start // End of testing code 10 | 11 | // Sum elements of array 12 | arraysum: 13 | MOV R2, #0 14 | LOOP: 15 | SUB R1, #1 16 | LDR R3, [R0, R1, LSL #2] 17 | ADD R2, R3 18 | CMP R1, #0 19 | BGT LOOP 20 | MOV R0, R2 21 | BX LR 22 | 23 | -------------------------------------------------------------------------------- /random.s: -------------------------------------------------------------------------------- 1 | .global _start 2 | _start: 3 | ldr r0, =2 // First function parameter is always passed through r0. 4 | bl random 5 | 1: b 1b // Done 6 | 7 | DATA: .word 1, 1, 134775813, 1 8 | random: 9 | CMP R0, #1 10 | BXLS LR 11 | PUSH {R4} 12 | LDR R3, =DATA 13 | LDM R3, {R1, R2, R3, R4} 14 | LOOP: 15 | MLA R2, R2, R3, R4 16 | ADD R1, #1 17 | CMP R1, R0 18 | BLO LOOP 19 | MOV R0, R2 20 | POP {R4} 21 | BX LR 22 | -------------------------------------------------------------------------------- /popcount.s: -------------------------------------------------------------------------------- 1 | .global _start 2 | _start: 3 | mov r0, #5 4 | bl popcount 5 | 1: b 1b // Done 6 | 7 | .global popcount 8 | popcount: 9 | MOV R1, #0 10 | LOOP: 11 | CMP R0, #0 12 | MOVEQ R0, R1 13 | BXEQ LR 14 | SUB R2, R0, #1 // x &= (x-1); Exploits bit pattern of 2's powers (more runtime efficient than using and for each bit) 15 | AND R0, R2 16 | ADD R1, #1 17 | B LOOP // "Expected solution length: Around 15 lines." ??? 18 | 19 | -------------------------------------------------------------------------------- /hailstone.s: -------------------------------------------------------------------------------- 1 | .global _start 2 | _start: 3 | mov r0, #5 4 | bl hailstone 5 | 1: b 1b // Done 6 | 7 | .global hailstone 8 | DATA: .word 0, 3, 1 9 | hailstone: 10 | PUSH {R4} 11 | LDR R1, =DATA 12 | LDM R1, {R1, R2, R3} 13 | LOOP: 14 | CMP R0, #1 15 | BEQ END 16 | AND R4, R0, #1 17 | CMP R4, #1 18 | MLAEQ R0, R0, R2, R3 19 | LSRNE R0, #1 20 | ADD R1, #1 21 | B LOOP 22 | END: 23 | MOV R0, R1 24 | POP {R4} 25 | BX LR 26 | -------------------------------------------------------------------------------- /memcpy.s: -------------------------------------------------------------------------------- 1 | .data 2 | .word 0x9999 3 | Dest: .word 0, 0, 0, 0, 0xaaaa 4 | Src: .word 1, 2, 3, 4, 0xbbbb 5 | 6 | .text 7 | .global _start 8 | _start: 9 | ldr r0, =Dest 10 | ldr r1, =Src 11 | ldr r2, =16 12 | bl memcpy 13 | 1: b 1b // Done 14 | 15 | .global memcpy 16 | memcpy: 17 | LOOP: 18 | CMP R2, #0 // If byte counter is 0, exit 19 | BXLE LR 20 | SUB R2, #1 21 | LDRB R3, [R1, R2] // Load byte 22 | STRB R3, [R0, R2] // Store byte 23 | B LOOP 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ASMBits-ARMv7 2 | 3 | By: Morris J Chen and Daniil Orekhov 4 | 5 | Other contributors: Michael de Biasio 6 | 7 |
8 | 9 | Solutions to ASMBits ARMv7 problem set. 10 | https://asmbits.01xz.net/wiki/Arm_index 11 | 12 |
13 | 14 | Special thanks to Daniil for correcting the stupidity in my code. 15 | 16 | If you come up with a more runtime efficient code, please let me know by posting an issue. 17 | 18 | Call me if-then-Elsa cuz the code never bothered me anyway. 19 | -------------------------------------------------------------------------------- /maxu.s: -------------------------------------------------------------------------------- 1 | // A test case to test your function with 2 | Array: .word 1, 2, 3 3 | 4 | .global _start 5 | _start: 6 | ldr r0, =3 7 | ldr r1, =Array 8 | bl max 9 | b _start // End of testing code 10 | 11 | // Return maximum element of unsigned array 12 | max: 13 | LDR R3, =0x00000000 // Smallest unsigned integer 14 | LOOP: 15 | SUB R0, #1 16 | LDR R2, [R1, R0, LSL #2] 17 | CMP R2, R3 18 | MOVHI R3, R2 19 | CMP R0, #0 20 | BNE LOOP 21 | MOV R0, R3 22 | BX LR 23 | 24 | -------------------------------------------------------------------------------- /decstr1.s: -------------------------------------------------------------------------------- 1 | // A test case to test your function with 2 | .data 3 | Str: .string "1234" 4 | .text 5 | .global _start 6 | _start: 7 | ldr r0, =Str 8 | bl decstr 9 | _end: b _end // End of testing code 10 | 11 | // Parse a decimal string 12 | decstr: 13 | PUSH {R4} 14 | MOV R2, #0 15 | MOV R4, #10 16 | LOOP: 17 | LDRB R1, [R0], #1 18 | CMP R1, #0 19 | BEQ END 20 | SUB R1, #0x30 21 | MLA R2, R2, R4, R1 22 | B LOOP 23 | END: 24 | MOV R0, R2 25 | POP {R4} 26 | BX LR 27 | 28 | -------------------------------------------------------------------------------- /strtolower.s: -------------------------------------------------------------------------------- 1 | .data 2 | .byte 0 // Strings aren't word-aligned 3 | MyString: .string "Hello World" 4 | 5 | .text 6 | .global _start 7 | _start: 8 | ldr r0, =MyString 9 | bl strtolower 10 | 1: b 1b 11 | 12 | .global strtolower 13 | strtolower: 14 | MOV R1, #0 15 | LOOP: 16 | LDRB R2, [R0, R1] 17 | CMP R2, #0 18 | BXEQ LR 19 | CMP R2, #0x41 // Compare to 'A' 20 | BLT LTA 21 | CMP R2, #0x5a // Compare to 'Z' 22 | ADDLE R2, #0x20 23 | LTA: 24 | STRB R2, [R0, R1] 25 | ADD R1, #1 26 | B LOOP 27 | -------------------------------------------------------------------------------- /maxs8.s: -------------------------------------------------------------------------------- 1 | // A test case to test your function with 2 | .data 3 | Array: .byte 1, 2, 3 4 | 5 | .text 6 | .global _start 7 | _start: 8 | ldr r0, =3 9 | ldr r1, =Array 10 | bl max 11 | b _start // End of testing code 12 | 13 | // Return maximum element of unsigned array 14 | max: 15 | LDR R3, =0x80000000 // Smallest signed integer 16 | LOOP: 17 | SUB R0, #1 18 | LDRB R2, [R1, R0] 19 | LSL R2, #24 20 | ASR R2, #24 21 | CMP R2, R3 22 | MOVGT R3, R2 23 | CMP R0, #0 24 | BNE LOOP 25 | MOV R0, R3 26 | BX LR 27 | -------------------------------------------------------------------------------- /mins.s: -------------------------------------------------------------------------------- 1 | // A test case to test your function with 2 | Array: .word 1, 2, 3 3 | 4 | .global _start 5 | _start: 6 | ldr r0, =3 7 | ldr r1, =Array 8 | bl min 9 | b _start // End of testing code 10 | 11 | // Return minimum element of signed array 12 | min: 13 | LDR R3, =0x7FFFFFFF // Largest signed integer 14 | LOOP: 15 | SUB R0, #1 16 | LDR R2, [R1, R0, LSL #2] // Read word at index R0 17 | 18 | CMP R2, R3 // Assign R3 the minimum 19 | MOVLT R3, R2 20 | 21 | CMP R0, #0 22 | MOVEQ R0, R3 23 | BXEQ LR 24 | 25 | B LOOP 26 | -------------------------------------------------------------------------------- /saturate2.s: -------------------------------------------------------------------------------- 1 | // A test case to test your function with 2 | .global _start 3 | _start: 4 | ldr r0, =0x123 // First parameter is always in r0 5 | bl saturate 6 | b _start // End of testing code 7 | 8 | // Convert signed 32 bit to 8 bit, with saturation 9 | saturate: 10 | CMP R0, #0 // Check positive/negative 11 | BLT NEG 12 | CMP R0, #0x7F 13 | MOVGT R0, #0x7F // Largest number possible 14 | BX LR 15 | NEG: 16 | CMP R0, #0xFFFFFF80 17 | MOVLT R0, #0x80 // Smallest number possible 18 | BICGE R0, #0xFFFFFF00 // Clear the upper bits 19 | BX LR 20 | -------------------------------------------------------------------------------- /peak.s: -------------------------------------------------------------------------------- 1 | // A test case to test your function with 2 | Array: .word 1, 2, 3 3 | 4 | .global _start 5 | _start: 6 | ldr r0, =3 7 | ldr r1, =Array 8 | bl peak 9 | b _start // End of testing code 10 | 11 | // Return the difference between max and min array elements 12 | peak: 13 | PUSH {R4} 14 | LDR R2, =0x7FFFFFFF 15 | LDR R3, =0x80000000 16 | LOOP: 17 | SUB R0, #1 18 | LDR R4, [R1, R0, LSL #2] 19 | CMP R4, R2 20 | MOVLT R2, R4 21 | CMP R4, R3 22 | MOVGT R3, R4 23 | CMP R0, #0 24 | BGT LOOP 25 | SUB R0, R3, R2 26 | POP {R4} 27 | BX LR 28 | 29 | -------------------------------------------------------------------------------- /extend.s: -------------------------------------------------------------------------------- 1 | // A test case to test your function with 2 | .global _start 3 | _start: 4 | ldr r0, =2 // 2 = sign extend 8->32 5 | ldr r1, =0xf0 // The number to extend 6 | bl extend 7 | b _start // End of testing code 8 | 9 | // A function to extend. Only this part will be tested. 10 | extend: 11 | CMP R0, #0 12 | BICEQ R1, #0xFFFFFF00 13 | 14 | CMP R0, #1 15 | LSLEQ R1, #16 16 | LSREQ R1, #16 17 | 18 | CMP R0, #2 19 | LSLEQ R1, #24 20 | ASREQ R1, #24 21 | 22 | CMP R0, #3 23 | LSLEQ R1, #16 24 | ASREQ R1, #16 25 | 26 | MOV R0, R1 27 | BX LR 28 | -------------------------------------------------------------------------------- /increment_align.s: -------------------------------------------------------------------------------- 1 | .data 2 | .byte 0 // Test with an unaligned word. 3 | Pointer: .word 1234 4 | .text 5 | .global _start 6 | _start: 7 | ldr r0, =Pointer 8 | bl inc 9 | 1: b 1b // Done 10 | 11 | .global inc 12 | inc: 13 | LDRB R1, [R0, #3] 14 | LDRB R2, [R0, #2] 15 | LSL R1, #8 16 | ADD R1, R2 17 | LDRB R2, [R0, #1] 18 | LSL R1, #8 19 | ADD R1, R2 20 | LDRB R2, [R0] 21 | LSL R1, #8 22 | ADD R1, R2 23 | ADD R1, #1 24 | STRB R1, [R0] 25 | LSR R1, #8 26 | STRB R1, [R0, #1] 27 | LSR R1, #8 28 | STRB R1, [R0, #2] 29 | LSR R1, #8 30 | STRB R1, [R0, #3] 31 | BX LR 32 | -------------------------------------------------------------------------------- /subarraysum.s: -------------------------------------------------------------------------------- 1 | // A test case to test your function with 2 | Array: .word -1, -1, 3, -1, 3, -2 3 | 4 | .global _start 5 | _start: 6 | ldr r0, =Array 7 | ldr r1, =6 8 | bl subarraysum 9 | b _start // End of testing code 10 | 11 | // Sum elements of array 12 | subarraysum: 13 | PUSH {R4} 14 | LDR R2, =0x80000000 // curr max 15 | MOV R3, R2 // tot max 16 | LOOP: 17 | SUB R1, #1 18 | LDR R4, [R0, R1, LSL #2] 19 | CMP R2, #0 20 | MOVLT R2, #0 21 | ADD R2, R4 22 | CMP R2, R3 23 | MOVGT R3, R2 24 | CMP R1, #0 25 | BGT LOOP 26 | POP {R4} 27 | MOV R0, R3 28 | BX LR 29 | 30 | -------------------------------------------------------------------------------- /arrayinsert.s: -------------------------------------------------------------------------------- 1 | .data 2 | // Leave some space for the expanded array 3 | Array: .word 1, 2, 3, 4, 0xff, 0xff 4 | 5 | .text 6 | .global _start 7 | _start: 8 | ldr r0, =Array 9 | ldr r1, =4 10 | ldr r2, =2 11 | ldr r3, =123 12 | bl array_insert 13 | 1: b 1b // Done 14 | 15 | array_insert: 16 | SUB R1, R2 17 | LDR R2, [R0, R2, LSL #2]! // R0 contains address of first element in range 18 | MOV R2, R0 19 | LDR R1, [R2, R1, LSL #2]! // R2 contains address of last element in range 20 | LOOP: 21 | LDR R1, [R2, #-4]! 22 | STR R1, [R2, #4] 23 | CMP R2, R0 24 | BGT LOOP 25 | STR R3, [R0] 26 | BX LR 27 | -------------------------------------------------------------------------------- /ifelse1.s: -------------------------------------------------------------------------------- 1 | // Some testing code 2 | // You may uncomment these during testing, but comment them out before submitting 3 | // odd: bx lr 4 | // even: bx lr 5 | 6 | .global _start 7 | _start: 8 | ldr r0, =1 // First function parameter is always passed through r0. 9 | bl oddeven 10 | 1: b 1b // Done 11 | 12 | oddeven: 13 | // Because there are nested function calls, lr needs to be saved and restored. 14 | push {lr} 15 | 16 | // Your code here 17 | AND R1, R0, #1 18 | CMP R1, #0 19 | BLEQ even 20 | BLNE odd 21 | 22 | // Restore lr and return. (This can be shortened to pop {pc} ) 23 | pop {lr} 24 | bx lr 25 | 26 | -------------------------------------------------------------------------------- /sum_args20.s: -------------------------------------------------------------------------------- 1 | .global _start 2 | _start: 3 | ldr sp, =0x04000000 // Initial sp 4 | sub sp, sp, #64 // 16 stack parameters 5 | mov r0, #5 6 | mov r1, #20 7 | mov r2, sp 8 | initloop: 9 | str r0, [r2], #4 // Post-indexed addressing: Add 4 to r2 after 10 | add r0, r0, #1 11 | cmp r0, r1 12 | ble initloop 13 | 14 | mov r0, #1 15 | mov r1, #2 16 | mov r2, #3 17 | mov r3, #4 18 | 19 | bl sum 20 | add sp, sp, #64 // Clean up stack 21 | 1: b 1b // done 22 | 23 | sum: 24 | PUSH {R0, R1, R2, R3} 25 | MOV R0, #0 26 | MOV R1, #0 27 | LOOP: 28 | LDR R2, [SP, R1, LSL #2] 29 | ADD R0, R2 30 | ADD R1, #1 31 | CMP R1, #20 32 | BLT LOOP 33 | 34 | POP {R1, R2, R3} 35 | POP {R1} 36 | 37 | BX LR 38 | --------------------------------------------------------------------------------