├── README.md └── examples ├── array.s ├── assembler_hello_world.s ├── compare_char.s ├── factorial.s ├── float_div.s ├── float_mult.s ├── float_scanf.s ├── hello_world.s ├── mod.s ├── printf.s ├── procedure_call.s ├── procedure_call_parameters.s ├── rand.s ├── rand_array.s ├── reg_dump.s └── scanf.s /README.md: -------------------------------------------------------------------------------- 1 | # cse2312 2 | CSE 2312: Computer Organization and Assembly Language Programming 3 | -------------------------------------------------------------------------------- /examples/array.s: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * @file array.s 3 | * @brief simple array declaration and iteration example 4 | * 5 | * Simple example of declaring a fixed-width array and traversing over the 6 | * elements for printing. 7 | * 8 | * @author Christopher D. McMurrough 9 | ******************************************************************************/ 10 | 11 | .global main 12 | .func main 13 | 14 | main: 15 | MOV R0, #0 @ initialze index variable 16 | writeloop: 17 | CMP R0, #100 @ check to see if we are done iterating 18 | BEQ writedone @ exit loop if done 19 | LDR R1, =a @ get address of a 20 | LSL R2, R0, #2 @ multiply index*4 to get array offset 21 | ADD R2, R1, R2 @ R2 now has the element address 22 | STR R2, [R2] @ write the address of a[i] to a[i] 23 | ADD R0, R0, #1 @ increment index 24 | B writeloop @ branch to next loop iteration 25 | writedone: 26 | MOV R0, #0 @ initialze index variable 27 | readloop: 28 | CMP R0, #100 @ check to see if we are done iterating 29 | BEQ readdone @ exit loop if done 30 | LDR R1, =a @ get address of a 31 | LSL R2, R0, #2 @ multiply index*4 to get array offset 32 | ADD R2, R1, R2 @ R2 now has the element address 33 | LDR R1, [R2] @ read the array at address 34 | PUSH {R0} @ backup register before printf 35 | PUSH {R1} @ backup register before printf 36 | PUSH {R2} @ backup register before printf 37 | MOV R2, R1 @ move array value to R2 for printf 38 | MOV R1, R0 @ move array index to R1 for printf 39 | BL _printf @ branch to print procedure with return 40 | POP {R2} @ restore register 41 | POP {R1} @ restore register 42 | POP {R0} @ restore register 43 | ADD R0, R0, #1 @ increment index 44 | B readloop @ branch to next loop iteration 45 | readdone: 46 | B _exit @ exit if done 47 | 48 | _exit: 49 | MOV R7, #4 @ write syscall, 4 50 | MOV R0, #1 @ output stream to monitor, 1 51 | MOV R2, #21 @ print string length 52 | LDR R1, =exit_str @ string at label exit_str: 53 | SWI 0 @ execute syscall 54 | MOV R7, #1 @ terminate syscall, 1 55 | SWI 0 @ execute syscall 56 | 57 | _printf: 58 | PUSH {LR} @ store the return address 59 | LDR R0, =printf_str @ R0 contains formatted string address 60 | BL printf @ call printf 61 | POP {PC} @ restore the stack pointer and return 62 | 63 | .data 64 | 65 | .balign 4 66 | a: .skip 400 67 | printf_str: .asciz "a[%d] = %d\n" 68 | exit_str: .ascii "Terminating program.\n" 69 | -------------------------------------------------------------------------------- /examples/assembler_hello_world.s: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * @file assembler_hello_world.s 3 | * @brief Hello world console print example using the GNU assembler 4 | * 5 | * Simple example of printing text to console using ARM assembly on Raspbian 6 | * Example based on "Raspberry Pi Assembly Language Raspbian" by Bruce Smith. 7 | * To assemble, run the following commands: 8 | * as -o assembler_hello_world.o assembler_hello_world.s 9 | * ld -o assembler_hello_world assembler_hello_world.s 10 | * 11 | * @author Christopher D. McMurrough 12 | ******************************************************************************/ 13 | 14 | .global _start 15 | 16 | _start: 17 | MOV R7, #4 @ write syscall, 4 18 | MOV R0, #1 @ output stream to monitor, 1 19 | MOV R2, #13 @ print string length 20 | LDR R1,=hello_str @ string at label hello_str: 21 | SWI 0 @ execute syscall 22 | B _exit @ branch to exit procedure 23 | 24 | _exit: 25 | MOV R7, #1 @ terminate syscall, 1 26 | SWI 0 @ execute syscall 27 | 28 | .data 29 | hello_str: 30 | .ascii "Hello World!\n" 31 | 32 | -------------------------------------------------------------------------------- /examples/compare_char.s: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * @file compare_char.s 3 | * @brief simple get keyboard character and compare 4 | * 5 | * Simple example of invoking syscall to retrieve a char from keyboard input, 6 | * and testing to see if it is equal to a given value 7 | * 8 | * @author Christopher D. McMurrough 9 | ******************************************************************************/ 10 | 11 | .global main 12 | .func main 13 | 14 | main: 15 | BL _prompt @ branch to printf procedure with return 16 | BL _getchar @ branch to scanf procedure with return 17 | MOV R1, R0 @ move return value R0 to argument register R1 18 | BL _compare @ check the scanf input 19 | B _exit @ branch to exit procedure with no return 20 | 21 | _exit: 22 | MOV R7, #4 @ write syscall, 4 23 | MOV R0, #1 @ output stream to monitor, 1 24 | MOV R2, #21 @ print string length 25 | LDR R1, =exit_str @ string at label exit_str: 26 | SWI 0 @ execute syscall 27 | MOV R7, #1 @ terminate syscall, 1 28 | SWI 0 @ execute syscall 29 | 30 | _prompt: 31 | MOV R7, #4 @ write syscall, 4 32 | MOV R0, #1 @ output stream to monitor, 1 33 | MOV R2, #23 @ print string length 34 | LDR R1, =prompt_str @ string at label prompt_str: 35 | SWI 0 @ execute syscall 36 | MOV PC, LR @ return 37 | 38 | _getchar: 39 | MOV R7, #3 @ write syscall, 3 40 | MOV R0, #0 @ input stream from monitor, 0 41 | MOV R2, #1 @ read a single character 42 | LDR R1, =read_char @ store the character in data memory 43 | SWI 0 @ execute the system call 44 | LDR R0, [R1] @ move the character to the return register 45 | AND R0, #0xFF @ mask out all but the lowest 8 bits 46 | MOV PC, LR @ return 47 | 48 | _compare: 49 | CMP R1, #'@' @ compare against the constant char '@' 50 | BEQ _correct @ branch to equal handler 51 | BNE _incorrect @ branch to not equal handler 52 | 53 | _correct: 54 | MOV R5, LR @ store LR since printf call overwrites 55 | LDR R0, =equal_str @ R0 contains formatted string address 56 | BL printf @ call printf 57 | MOV PC, R5 @ return 58 | 59 | _incorrect: 60 | MOV R5, LR @ store LR since printf call overwrites 61 | LDR R0, =nequal_str @ R0 contains formatted string address 62 | BL printf @ call printf 63 | MOV PC, R5 @ return 64 | 65 | .data 66 | read_char: .ascii " " 67 | prompt_str: .ascii "Enter the @ character: " 68 | equal_str: .asciz "CORRECT \n" 69 | nequal_str: .asciz "INCORRECT: %c \n" 70 | exit_str: .ascii "Terminating program.\n" 71 | -------------------------------------------------------------------------------- /examples/factorial.s: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * @file factorial.s 3 | * @brief simple recursion example 4 | * 5 | * Simple example of recursion and stack management 6 | * 7 | * @author Christopher D. McMurrough 8 | ******************************************************************************/ 9 | 10 | .global main 11 | .func main 12 | 13 | main: 14 | BL _prompt @ branch to prompt procedure with return 15 | BL _scanf @ branch to scan procedure with return 16 | MOV R4, R0 @ store n in R4 17 | MOV R1, R0 @ pass n to factorial procedure 18 | BL _fact @ branch to factorial procedure with return 19 | MOV R1, R4 @ pass n to printf procedure 20 | MOV R2, R0 @ pass result to printf procedure 21 | BL _printf @ branch to print procedure with return 22 | B _exit @ branch to exit procedure with no return 23 | 24 | _exit: 25 | MOV R7, #4 @ write syscall, 4 26 | MOV R0, #1 @ output stream to monitor, 1 27 | MOV R2, #21 @ print string length 28 | LDR R1, =exit_str @ string at label exit_str: 29 | SWI 0 @ execute syscall 30 | MOV R7, #1 @ terminate syscall, 1 31 | SWI 0 @ execute syscall 32 | 33 | _prompt: 34 | PUSH {R1} @ backup register value 35 | PUSH {R2} @ backup register value 36 | PUSH {R7} @ backup register value 37 | MOV R7, #4 @ write syscall, 4 38 | MOV R0, #1 @ output stream to monitor, 1 39 | MOV R2, #26 @ print string length 40 | LDR R1, =prompt_str @ string at label prompt_str: 41 | SWI 0 @ execute syscall 42 | POP {R7} @ restore register value 43 | POP {R2} @ restore register value 44 | POP {R1} @ restore register value 45 | MOV PC, LR @ return 46 | 47 | _printf: 48 | PUSH {LR} @ store the return address 49 | LDR R0, =printf_str @ R0 contains formatted string address 50 | @MOV R1, R1 @ R1 contains printf argument 1 (redundant line) 51 | @MOV R2, R2 @ R2 contains printf argument 2 (redundant line) 52 | BL printf @ call printf 53 | POP {PC} @ restore the stack pointer and return 54 | 55 | _scanf: 56 | PUSH {LR} @ store the return address 57 | PUSH {R1} @ backup regsiter value 58 | LDR R0, =format_str @ R0 contains address of format string 59 | SUB SP, SP, #4 @ make room on stack 60 | MOV R1, SP @ move SP to R1 to store entry on stack 61 | BL scanf @ call scanf 62 | LDR R0, [SP] @ load value at SP into R0 63 | ADD SP, SP, #4 @ remove value from stack 64 | POP {R1} @ restore register value 65 | POP {PC} @ restore the stack pointer and return 66 | 67 | _fact: 68 | PUSH {LR} @ store the return address 69 | CMP R1, #1 @ compare the input argument to 1 70 | MOVEQ R0, #1 @ set return value to 1 if equal 71 | POPEQ {PC} @ restore stack pointer and return if equal 72 | 73 | PUSH {R1} @ backup input argument value 74 | SUB R1, R1, #1 @ decrement the input argument 75 | BL _fact @ compute fact(n-1) 76 | POP {R1} @ restore input argument 77 | MUL R0, R0, R1 @ compute fact(n-1)*n 78 | POP {PC} @ restore the stack pointer and return 79 | 80 | .data 81 | number: .word 0 82 | format_str: .asciz "%d" 83 | prompt_str: .asciz "Enter a positive number: " 84 | printf_str: .asciz "%d! = %d\n" 85 | exit_str: .ascii "Terminating program.\n" 86 | -------------------------------------------------------------------------------- /examples/float_div.s: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * @file float_div.s 3 | * @brief simple example of integer division with a scalar result using the FPU 4 | * 5 | * Simple example of using the ARM FPU to compute the division result of 6 | * two integer values 7 | * 8 | * @author Christopher D. McMurrough 9 | ******************************************************************************/ 10 | 11 | .global main 12 | .func main 13 | 14 | main: 15 | MOV R0, #22 @ load the numerator 16 | MOV R1, #7 @ load the denominator 17 | VMOV S0, R0 @ move the numerator to floating point register 18 | VMOV S1, R1 @ move the denominator to floating point register 19 | VCVT.F32.U32 S0, S0 @ convert unsigned bit representation to single float 20 | VCVT.F32.U32 S1, S1 @ convert unsigned bit representation to single float 21 | 22 | VDIV.F32 S2, S0, S1 @ compute S2 = S0 * S1 23 | 24 | VCVT.F64.F32 D4, S2 @ covert the result to double precision for printing 25 | VMOV R1, R2, D4 @ split the double VFP register into two ARM registers 26 | BL _printf_result @ print the result 27 | 28 | B _exit @ branch to exit procedure with no return 29 | 30 | _exit: 31 | MOV R7, #4 @ write syscall, 4 32 | MOV R0, #1 @ output stream to monitor, 1 33 | MOV R2, #21 @ print string length 34 | LDR R1, =exit_str @ string at label exit_str: 35 | SWI 0 @ execute syscall 36 | MOV R7, #1 @ terminate syscall, 1 37 | SWI 0 @ execute syscall 38 | 39 | _printf_result: 40 | PUSH {LR} @ push LR to stack 41 | LDR R0, =result_str @ R0 contains formatted string address 42 | BL printf @ call printf 43 | POP {PC} @ pop LR from stack and return 44 | 45 | .data 46 | result_str: .asciz "Pi is approximately 22/7 = %f \n" 47 | exit_str: .ascii "Terminating program.\n" 48 | -------------------------------------------------------------------------------- /examples/float_mult.s: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * @file float_mult.s 3 | * @brief simple example of scalar multiplication using the FPU 4 | * 5 | * Simple example of using the ARM FPU to compute the multiplication result of 6 | * two float values 7 | * 8 | * @author Christopher D. McMurrough 9 | ******************************************************************************/ 10 | 11 | .global main 12 | .func main 13 | 14 | main: 15 | 16 | LDR R0, =val1 @ load variable address 17 | VLDR S0, [R0] @ load the value into the VFP register 18 | 19 | LDR R0, =val2 @ load variable address 20 | VLDR S1, [R0] @ load the value into the VFP register 21 | 22 | VMUL.F32 S2, S0, S1 @ compute S2 = S0 * S1 23 | 24 | VCVT.F64.F32 D4, S2 @ covert the result to double precision for printing 25 | VMOV R1, R2, D4 @ split the double VFP register into two ARM registers 26 | BL _printf_result @ print the result 27 | 28 | B _exit @ branch to exit procedure with no return 29 | 30 | _exit: 31 | MOV R7, #4 @ write syscall, 4 32 | MOV R0, #1 @ output stream to monitor, 1 33 | MOV R2, #21 @ print string length 34 | LDR R1, =exit_str @ string at label exit_str: 35 | SWI 0 @ execute syscall 36 | MOV R7, #1 @ terminate syscall, 1 37 | SWI 0 @ execute syscall 38 | 39 | _printf_result: 40 | PUSH {LR} @ push LR to stack 41 | LDR R0, =result_str @ R0 contains formatted string address 42 | BL printf @ call printf 43 | POP {PC} @ pop LR from stack and return 44 | 45 | .data 46 | result_str: .asciz "Multiplication result = %f \n" 47 | exit_str: .ascii "Terminating program.\n" 48 | val1: .float 3.14159 49 | val2: .float 0.100 50 | -------------------------------------------------------------------------------- /examples/float_scanf.s: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * @file float_scanf.s 3 | * @brief example of obtaining a floating point value using scanf 4 | * 5 | * Obtains a floating point value using scanf. The single precision number is 6 | * stored in memory by scanf and then returned in R0. R0 is then moved to S0, 7 | * where it is converted to double precision in D1. D1 is then split into R1 and 8 | * R2 for compatability with printf. 9 | * 10 | * @author Christopher D. McMurrough 11 | ******************************************************************************/ 12 | 13 | .global main 14 | .func main 15 | 16 | main: 17 | BL _prompt @ branch to prompt procedure with return 18 | BL _scanf @ branch to scanf procedure with return 19 | VMOV S0, R0 @ move return value R0 to FPU register S0 20 | VCVT.F64.F32 D1, S0 @ covert the result to double precision for printing 21 | VMOV R1, R2, D1 @ split the double VFP register into two ARM registers 22 | BL _printf @ branch to print procedure with return 23 | B _exit @ branch to exit procedure with no return 24 | 25 | _exit: 26 | MOV R7, #4 @ write syscall, 4 27 | MOV R0, #1 @ output stream to monitor, 1 28 | MOV R2, #21 @ print string length 29 | LDR R1, =exit_str @ string at label exit_str: 30 | SWI 0 @ execute syscall 31 | MOV R7, #1 @ terminate syscall, 1 32 | SWI 0 @ execute syscall 33 | 34 | _prompt: 35 | MOV R7, #4 @ write syscall, 4 36 | MOV R0, #1 @ output stream to monitor, 1 37 | MOV R2, #31 @ print string length 38 | LDR R1, =prompt_str @ string at label prompt_str: 39 | SWI 0 @ execute syscall 40 | MOV PC, LR @ return 41 | 42 | _printf: 43 | PUSH {LR} @ push LR to stack 44 | LDR R0, =printf_str @ R0 contains formatted string address 45 | BL printf @ call printf 46 | POP {PC} @ pop LR from stack and return 47 | 48 | _scanf: 49 | PUSH {LR} @ store LR since scanf call overwrites 50 | SUB SP, SP, #4 @ make room on stack 51 | LDR R0, =format_str @ R0 contains address of format string 52 | MOV R1, SP @ move SP to R1 to store entry on stack 53 | BL scanf @ call scanf 54 | LDR R0, [SP] @ load value at SP into R0 55 | ADD SP, SP, #4 @ restore the stack pointer 56 | POP {PC} @ return 57 | 58 | .data 59 | format_str: .asciz "%f" 60 | prompt_str: .asciz "Type a number and press enter: " 61 | printf_str: .asciz "The number entered was: %f\n" 62 | exit_str: .ascii "Terminating program.\n" 63 | -------------------------------------------------------------------------------- /examples/hello_world.s: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * @file hello_world.s 3 | * @brief Simple hello world example using printf 4 | * @author Christopher D. McMurrough 5 | ******************************************************************************/ 6 | 7 | .global main 8 | .func main 9 | 10 | main: 11 | LDR R0,=print_str @ store string address in R0 12 | BL printf @ call printf 13 | B _exit @ branch to exit procedure with no return 14 | 15 | _exit: 16 | MOV R7, #1 @ terminate syscall, 1 17 | SWI 0 @ execute syscall 18 | 19 | .data 20 | print_str: .asciz "Hello World!\n" 21 | -------------------------------------------------------------------------------- /examples/mod.s: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * @file mod.s 3 | * @brief simple mod operations example 4 | * 5 | * Simple example of computing the remainder of integer division 6 | * 7 | * @author Christopher D. McMurrough 8 | ******************************************************************************/ 9 | 10 | .global main 11 | .func main 12 | 13 | main: 14 | MOV R1, #200 @ set a constant value for mod evaluation 15 | MOV R2, #75 @ set a constant value for mod evaluation 16 | PUSH {R1} @ store value to stack 17 | PUSH {R2} @ store value to stack 18 | BL _mod_unsigned @ compute the remainder of R1 / R2 19 | POP {R2} @ restore values from stack 20 | POP {R1} @ restore values from stack 21 | MOV R3, R0 @ copy mod result to R3 22 | BL _print @ branch to print procedure with return 23 | B _exit @ branch to exit procedure with no return 24 | 25 | _exit: 26 | MOV R7, #4 @ write syscall, 4 27 | MOV R0, #1 @ output stream to monitor, 1 28 | MOV R2, #21 @ print string length 29 | LDR R1,=exit_str @ string at label exit_str: 30 | SWI 0 @ execute syscall 31 | MOV R7, #1 @ terminate syscall, 1 32 | SWI 0 @ execute syscall 33 | 34 | _mod_unsigned: 35 | cmp R2, R1 @ check to see if R1 >= R2 36 | MOVHS R0, R1 @ swap R1 and R2 if R2 > R1 37 | MOVHS R1, R2 @ swap R1 and R2 if R2 > R1 38 | MOVHS R2, R0 @ swap R1 and R2 if R2 > R1 39 | MOV R0, #0 @ initialize return value 40 | B _modloopcheck @ check to see if 41 | _modloop: 42 | ADD R0, R0, #1 @ increment R0 43 | SUB R1, R1, R2 @ subtract R2 from R1 44 | _modloopcheck: 45 | CMP R1, R2 @ check for loop termination 46 | BHS _modloop @ continue loop if R1 >= R2 47 | MOV R0, R1 @ move remainder to R0 48 | MOV PC, LR @ return 49 | 50 | _print: 51 | MOV R4, LR @ store LR since printf call overwrites 52 | LDR R0,=print_str @ R0 contains formatted string address 53 | BL printf @ call printf 54 | MOV PC, R4 @ return 55 | 56 | .data 57 | print_str: 58 | .asciz "%d mod %d = %d \n" 59 | exit_str: 60 | .ascii "Terminating program.\n" -------------------------------------------------------------------------------- /examples/printf.s: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * @file printf.s 3 | * @brief simple printf example 4 | * 5 | * Simple example of invoking printf to print a formatted string 6 | * 7 | * @author Christopher D. McMurrough 8 | ******************************************************************************/ 9 | 10 | .global main 11 | .func main 12 | 13 | main: 14 | BL _print @ branch to print procedure with return 15 | B _exit @ branch to exit procedure with no return 16 | 17 | _exit: 18 | MOV R7, #4 @ write syscall, 4 19 | MOV R0, #1 @ output stream to monitor, 1 20 | MOV R2, #21 @ print string length 21 | LDR R1,=exit_str @ string at label exit_str: 22 | SWI 0 @ execute syscall 23 | MOV R7, #1 @ terminate syscall, 1 24 | SWI 0 @ execute syscall 25 | 26 | _print: 27 | MOV R4, LR @ store LR since printf call overwrites 28 | LDR R0,=print_str @ R0 contains formatted string address 29 | MOV R1, #100 @ printf argument 1 30 | MOV R2, #200 @ printf argument 2 31 | MOV R3, #300 @ printf argument 3 32 | BL printf @ call printf 33 | MOV PC, R4 @ return 34 | 35 | .data 36 | print_str: 37 | .asciz "Printing 3 numbers: %d %d %d \n" 38 | exit_str: 39 | .ascii "Terminating program.\n" 40 | -------------------------------------------------------------------------------- /examples/procedure_call.s: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * @file procedure_call.s 3 | * @brief procedure call and return example 4 | * 5 | * Simple example of executing a procedure call and returning upon completion 6 | * 7 | * @author Christopher D. McMurrough 8 | ******************************************************************************/ 9 | 10 | .global _start 11 | 12 | _start: 13 | BL _hello @ branch to hello procedure with return 14 | B _exit @ branch to exit procedure with no return 15 | 16 | _exit: 17 | MOV R7, #4 @ write syscall, 4 18 | MOV R0, #1 @ output stream to monitor, 1 19 | MOV R2, #21 @ print string length 20 | LDR R1,=exit_str @ string at label exit_str: 21 | SWI 0 @ execute syscall 22 | 23 | MOV R7, #1 @ terminate syscall, 1 24 | SWI 0 @ execute syscall 25 | 26 | _hello: 27 | MOV R7, #4 @ write syscall, 4 28 | MOV R0, #1 @ output stream to monitor, 1 29 | MOV R2, #27 @ print string length 30 | LDR R1,=hello_str @ string at label hello_str: 31 | SWI 0 @ execute syscall 32 | MOV PC, LR @ return 33 | 34 | .data 35 | hello_str: 36 | .ascii "Hello from procedure call!\n" 37 | exit_str: 38 | .ascii "Terminating program.\n" 39 | -------------------------------------------------------------------------------- /examples/procedure_call_parameters.s: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * @file procedure_call_parameters.s 3 | * @brief procedure call and return example with passed parameters 4 | * 5 | * Simple example of executing a procedure call and returning upon completion. 6 | * The procedure call expects 3 input parameters, and returns a value. 7 | * 8 | * @author Christopher D. McMurrough 9 | ******************************************************************************/ 10 | 11 | .global main 12 | .func main 13 | 14 | main: 15 | MOV R1, #100 @ define function argument 1 16 | MOV R2, #20 @ define function argument 1 17 | MOV R3, #3 @ define function argument 1 18 | BL _add @ branch to hello procedure with return 19 | MOV R1, R0 @ copy return value to R1 20 | BL _print_val @ print value stored in R1 21 | B _exit @ branch to exit procedure with no return 22 | 23 | _exit: 24 | MOV R7, #4 @ write syscall, 4 25 | MOV R0, #1 @ output stream to monitor, 1 26 | MOV R2, #21 @ print string length 27 | LDR R1,=exit_str @ string at label exit_str: 28 | SWI 0 @ execute syscall 29 | 30 | MOV R7, #1 @ terminate syscall, 1 31 | SWI 0 @ execute syscall 32 | 33 | _add: 34 | MOV R0, R1 @ copy input register R1 to return register R0 35 | ADD R0, R2 @ add input register R2 to return register R0 36 | ADD R0, R3 @ add input register R3 to return register R0 37 | MOV PC, LR @ return 38 | 39 | _print_val: 40 | MOV R4, LR @ store LR since printf call overwrites 41 | LDR R0,=result_str @ string at label hello_str: 42 | BL printf @ call printf, where R1 is the print argument 43 | MOV LR, R4 @ restore LR from R4 44 | MOV PC, LR @ return 45 | 46 | .data 47 | add_str: 48 | .ascii "Adding numbers...\n" 49 | result_str: 50 | .asciz "Sum = %d\n" 51 | exit_str: 52 | .ascii "Terminating program.\n" 53 | -------------------------------------------------------------------------------- /examples/rand.s: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * @file rand.s 3 | * @brief simple pseudo-random number generation 4 | * 5 | * Simple example of generating a pseudo-random number using libc 6 | * 7 | * @author Christopher D. McMurrough 8 | ******************************************************************************/ 9 | 10 | .global main 11 | .func main 12 | 13 | main: 14 | BL _seedrand @ seed the random number generator with the current time 15 | BL _getrand @ get the random number 16 | MOV R1, R0 @ move the result into R1 for printf 17 | BL _printf @ print the random number 18 | BL _getrand @ get the random number 19 | MOV R1, R0 @ move the result into R1 for printf 20 | BL _printf @ print the random number 21 | BL _getrand @ get the random number 22 | MOV R1, R0 @ move the result into R1 for printf 23 | BL _printf @ print the random number 24 | B _exit @ exit if done 25 | 26 | _seedrand: 27 | PUSH {LR} @ backup return address 28 | MOV R0, #0 @ pass 0 as argument to time call 29 | BL time @ get system time 30 | MOV R1, R0 @ pass sytem time as argument to srand 31 | BL srand @ seed the random number generator 32 | POP {PC} @ return 33 | 34 | _getrand: 35 | PUSH {LR} @ backup return address 36 | BL rand @ get a random number 37 | POP {PC} @ return 38 | 39 | _exit: 40 | MOV R7, #4 @ write syscall, 4 41 | MOV R0, #1 @ output stream to monitor, 1 42 | MOV R2, #21 @ print string length 43 | LDR R1, =exit_str @ string at label exit_str: 44 | SWI 0 @ execute syscall 45 | MOV R7, #1 @ terminate syscall, 1 46 | SWI 0 @ execute syscall 47 | 48 | _printf: 49 | PUSH {LR} @ store the return address 50 | LDR R0, =printf_str @ R0 contains formatted string address 51 | BL printf @ call printf 52 | POP {PC} @ restore the stack pointer and return 53 | 54 | .data 55 | printf_str: .asciz "A random number: %d\n" 56 | exit_str: .ascii "Terminating program.\n" 57 | -------------------------------------------------------------------------------- /examples/rand_array.s: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * @file rand_array.s 3 | * @author Christopher D. McMurrough 4 | ******************************************************************************/ 5 | 6 | .global main 7 | .func main 8 | 9 | main: 10 | BL _seedrand @ seed random number generator with current time 11 | MOV R0, #0 @ initialze index variable 12 | writeloop: 13 | CMP R0, #100 @ check to see if we are done iterating 14 | BEQ writedone @ exit loop if done 15 | LDR R1, =a @ get address of a 16 | LSL R2, R0, #2 @ multiply index*4 to get array offset 17 | ADD R2, R1, R2 @ R2 now has the element address 18 | PUSH {R0} @ backup iterator before procedure call 19 | PUSH {R2} @ backup element address before procedure call 20 | BL _getrand @ get a random number 21 | POP {R2} @ restore element address 22 | STR R0, [R2] @ write the address of a[i] to a[i] 23 | POP {R0} @ restore iterator 24 | ADD R0, R0, #1 @ increment index 25 | B writeloop @ branch to next loop iteration 26 | writedone: 27 | MOV R0, #0 @ initialze index variable 28 | readloop: 29 | CMP R0, #100 @ check to see if we are done iterating 30 | BEQ readdone @ exit loop if done 31 | LDR R1, =a @ get address of a 32 | LSL R2, R0, #2 @ multiply index*4 to get array offset 33 | ADD R2, R1, R2 @ R2 now has the element address 34 | LDR R1, [R2] @ read the array at address 35 | PUSH {R0} @ backup register before printf 36 | PUSH {R1} @ backup register before printf 37 | PUSH {R2} @ backup register before printf 38 | MOV R2, R1 @ move array value to R2 for printf 39 | MOV R1, R0 @ move array index to R1 for printf 40 | BL _printf @ branch to print procedure with return 41 | POP {R2} @ restore register 42 | POP {R1} @ restore register 43 | POP {R0} @ restore register 44 | ADD R0, R0, #1 @ increment index 45 | B readloop @ branch to next loop iteration 46 | readdone: 47 | B _exit @ exit if done 48 | 49 | _exit: 50 | MOV R7, #4 @ write syscall, 4 51 | MOV R0, #1 @ output stream to monitor, 1 52 | MOV R2, #21 @ print string length 53 | LDR R1, =exit_str @ string at label exit_str: 54 | SWI 0 @ execute syscall 55 | MOV R7, #1 @ terminate syscall, 1 56 | SWI 0 @ execute syscall 57 | 58 | _printf: 59 | PUSH {LR} @ store the return address 60 | LDR R0, =printf_str @ R0 contains formatted string address 61 | BL printf @ call printf 62 | POP {PC} @ restore the stack pointer and return 63 | 64 | _seedrand: 65 | PUSH {LR} @ backup return address 66 | MOV R0, #0 @ pass 0 as argument to time call 67 | BL time @ get system time 68 | MOV R1, R0 @ pass sytem time as argument to srand 69 | BL srand @ seed the random number generator 70 | POP {PC} @ return 71 | 72 | _getrand: 73 | PUSH {LR} @ backup return address 74 | BL rand @ get a random number 75 | POP {PC} @ return 76 | 77 | .data 78 | 79 | .balign 4 80 | a: .skip 400 81 | printf_str: .asciz "a[%d] = %d\n" 82 | debug_str: 83 | .asciz "R%-2d 0x%08X %011d \n" 84 | exit_str: .ascii "Terminating program.\n" 85 | -------------------------------------------------------------------------------- /examples/reg_dump.s: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * @file reg_dump.s 3 | * @brief register print example 4 | * 5 | * Simple example of printing register values to terminal for debugging 6 | * 7 | * @author Christopher D. McMurrough 8 | ******************************************************************************/ 9 | 10 | .global main 11 | .func main 12 | 13 | main: 14 | MOV R0, #0 @ set a constant value for printing 15 | MOV R1, #10 @ set a constant value for printing 16 | MOV R2, #20 @ set a constant value for printing 17 | MOV R3, #30 @ set a constant value for printing 18 | MOV R4, #40 @ set a constant value for printing 19 | MOV R5, #50 @ set a constant value for printing 20 | MOV R6, #60 @ set a constant value for printing 21 | MOV R7, #70 @ set a constant value for printing 22 | MOV R8, #80 @ set a constant value for printing 23 | MOV R9, #90 @ set a constant value for printing 24 | MOV R10, #100 @ set a constant value for printing 25 | MOV R11, #110 @ set a constant value for printing 26 | MOV R12, #120 @ set a constant value for printing 27 | BL _reg_dump @ print register contents 28 | B _exit @ branch to exit procedure with no return 29 | 30 | _exit: 31 | MOV R7, #4 @ write syscall, 4 32 | MOV R0, #1 @ output stream to monitor, 1 33 | MOV R2, #21 @ print string length 34 | LDR R1,=exit_str @ string at label exit_str: 35 | SWI 0 @ execute syscall 36 | MOV R7, #1 @ terminate syscall, 1 37 | SWI 0 @ execute syscall 38 | 39 | _reg_dump: 40 | PUSH {LR} @ backup registers 41 | PUSH {R0} @ backup registers 42 | PUSH {R1} @ backup registers 43 | PUSH {R2} @ backup registers 44 | PUSH {R3} @ backup registers 45 | 46 | PUSH {R14} @ push registers for printing 47 | PUSH {R13} @ push registers for printing 48 | PUSH {R12} @ push registers for printing 49 | PUSH {R11} @ push registers for printing 50 | PUSH {R10} @ push registers for printing 51 | PUSH {R9} @ push registers for printing 52 | PUSH {R8} @ push registers for printing 53 | PUSH {R7} @ push registers for printing 54 | PUSH {R6} @ push registers for printing 55 | PUSH {R5} @ push registers for printing 56 | PUSH {R4} @ push registers for printing 57 | PUSH {R3} @ push registers for printing 58 | PUSH {R2} @ push registers for printing 59 | PUSH {R1} @ push registers for printing 60 | PUSH {R0} @ push registers for printing 61 | 62 | LDR R0,=debug_str @ prepare register print 63 | MOV R1, #0 @ prepare R0 print 64 | POP {R2} @ prepare R0 print 65 | MOV R3, R2 @ prepare R0 print 66 | BL printf @ print R0 value prior to reg_dump call 67 | 68 | LDR R0,=debug_str @ prepare register print 69 | MOV R1, #1 @ prepare R1 print 70 | POP {R2} @ prepare R1 print 71 | MOV R3, R2 @ prepare R1 print 72 | BL printf @ print R1 value prior to reg_dump call 73 | 74 | LDR R0,=debug_str @ prepare register print 75 | MOV R1, #2 @ prepare R2 print 76 | POP {R2} @ prepare R2 print 77 | MOV R3, R2 @ prepare R2 print 78 | BL printf @ print R2 value prior to reg_dump call 79 | 80 | LDR R0,=debug_str @ prepare register print 81 | MOV R1, #3 @ prepare R3 print 82 | POP {R2} @ prepare R3 print 83 | MOV R3, R2 @ prepare R3 print 84 | BL printf @ print R3 value prior to reg_dump call 85 | 86 | LDR R0,=debug_str @ prepare register print 87 | MOV R1, #4 @ prepare R4 print 88 | POP {R2} @ prepare R4 print 89 | MOV R3, R2 @ prepare R4 print 90 | BL printf @ print R4 value prior to reg_dump call 91 | 92 | LDR R0,=debug_str @ prepare register print 93 | MOV R1, #5 @ prepare R5 print 94 | POP {R2} @ prepare R5 print 95 | MOV R3, R2 @ prepare R5 print 96 | BL printf @ print R5 value prior to reg_dump call 97 | 98 | LDR R0,=debug_str @ prepare register print 99 | MOV R1, #6 @ prepare R6 print 100 | POP {R2} @ prepare R6 print 101 | MOV R3, R2 @ prepare R6 print 102 | BL printf @ print R6 value prior to reg_dump call 103 | 104 | LDR R0,=debug_str @ prepare register print 105 | MOV R1, #7 @ prepare R7 print 106 | POP {R2} @ prepare R7 print 107 | MOV R3, R2 @ prepare R7 print 108 | BL printf @ print R7 value prior to reg_dump call 109 | 110 | LDR R0,=debug_str @ prepare register print 111 | MOV R1, #8 @ prepare R8 print 112 | POP {R2} @ prepare R8 print 113 | MOV R3, R2 @ prepare R8 print 114 | BL printf @ print R8 value prior to reg_dump call 115 | 116 | LDR R0,=debug_str @ prepare register print 117 | MOV R1, #9 @ prepare R9 print 118 | POP {R2} @ prepare R9 print 119 | MOV R3, R2 @ prepare R9 print 120 | BL printf @ print R9 value prior to reg_dump call 121 | 122 | LDR R0,=debug_str @ prepare register print 123 | MOV R1, #10 @ prepare R10 print 124 | POP {R2} @ prepare R10 print 125 | MOV R3, R2 @ prepare R10 print 126 | BL printf @ print R10 value prior to reg_dump call 127 | 128 | LDR R0,=debug_str @ prepare register print 129 | MOV R1, #11 @ prepare R11 print 130 | POP {R2} @ prepare R11 print 131 | MOV R3, R2 @ prepare R11 print 132 | BL printf @ print R11 value prior to reg_dump call 133 | 134 | LDR R0,=debug_str @ prepare register print 135 | MOV R1, #12 @ prepare R12 print 136 | POP {R2} @ prepare R12 print 137 | MOV R3, R2 @ prepare R12 print 138 | BL printf @ print R12 value prior to reg_dump call 139 | 140 | LDR R0,=debug_str @ prepare register print 141 | MOV R1, #13 @ prepare R13 print 142 | POP {R2} @ prepare R13 print 143 | MOV R3, R2 @ prepare R13 print 144 | BL printf @ print R13 value prior to reg_dump call 145 | 146 | LDR R0,=debug_str @ prepare register print 147 | MOV R1, #14 @ prepare R14 print 148 | POP {R2} @ prepare R14 print 149 | MOV R3, R2 @ prepare R14 print 150 | BL printf @ print R14 value prior to reg_dump call 151 | 152 | POP {R3} @ restore register 153 | POP {R2} @ restore register 154 | POP {R1} @ restore register 155 | POP {R0} @ restore regsiter 156 | POP {PC} @ return 157 | 158 | .data 159 | debug_str: 160 | .asciz "R%-2d 0x%08X %011d \n" 161 | exit_str: 162 | .ascii "Terminating program.\n" 163 | -------------------------------------------------------------------------------- /examples/scanf.s: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | * @file scanf.s 3 | * @brief simple scanf example 4 | * 5 | * Simple example of invoking scanf to retrieve a number from keyboard input 6 | * 7 | * @author Christopher D. McMurrough 8 | ******************************************************************************/ 9 | 10 | .global main 11 | .func main 12 | 13 | main: 14 | BL _prompt @ branch to prompt procedure with return 15 | BL _scanf @ branch to scanf procedure with return 16 | MOV R1, R0 @ move return value R0 to argument register R1 17 | BL _printf @ branch to print procedure with return 18 | B _exit @ branch to exit procedure with no return 19 | 20 | _exit: 21 | MOV R7, #4 @ write syscall, 4 22 | MOV R0, #1 @ output stream to monitor, 1 23 | MOV R2, #21 @ print string length 24 | LDR R1, =exit_str @ string at label exit_str: 25 | SWI 0 @ execute syscall 26 | MOV R7, #1 @ terminate syscall, 1 27 | SWI 0 @ execute syscall 28 | 29 | _prompt: 30 | MOV R7, #4 @ write syscall, 4 31 | MOV R0, #1 @ output stream to monitor, 1 32 | MOV R2, #31 @ print string length 33 | LDR R1, =prompt_str @ string at label prompt_str: 34 | SWI 0 @ execute syscall 35 | MOV PC, LR @ return 36 | 37 | _printf: 38 | MOV R4, LR @ store LR since printf call overwrites 39 | LDR R0, =printf_str @ R0 contains formatted string address 40 | MOV R1, R1 @ R1 contains printf argument (redundant line) 41 | BL printf @ call printf 42 | MOV PC, R4 @ return 43 | 44 | _scanf: 45 | PUSH {LR} @ store LR since scanf call overwrites 46 | SUB SP, SP, #4 @ make room on stack 47 | LDR R0, =format_str @ R0 contains address of format string 48 | MOV R1, SP @ move SP to R1 to store entry on stack 49 | BL scanf @ call scanf 50 | LDR R0, [SP] @ load value at SP into R0 51 | ADD SP, SP, #4 @ restore the stack pointer 52 | POP {PC} @ return 53 | 54 | .data 55 | format_str: .asciz "%d" 56 | prompt_str: .asciz "Type a number and press enter: " 57 | printf_str: .asciz "The number entered was: %d\n" 58 | exit_str: .ascii "Terminating program.\n" 59 | --------------------------------------------------------------------------------