Code Examples from Class
Jump to navigation
Jump to search
- Factorial
; Factorial Calculation ; The answer is in R10 ; Rob Frohne 2013 GLOBAL Reset_Handler AREA Factorial, CODE, READONLY ENTRY Reset_Handler movs r8, #0 ; Take the factorial of this number, n. mov r10, #1 ; 0! and 1! are 1 beq stop ; If r8 is zero we are done cmp r8, #1 ; If r8 is 1, beq stop ; we are done subs r9, r8, #1 ; n-1 loop mulne r10, r9, r8 ; n(n-1) mov r8, r10 subs r9, r9, #1 bne loop stop b stop END
- 64 Bit Add
VAL1A EQU 0xffffffff VAL1B EQU 0x0000000f VAL2A EQU 0x00000001 VAL2B EQU 0x00000001 AREA LongAdd, CODE ENTRY ldr R0, = VAL1A ldr R1, = VAL1B ldr R2, = VAL2A ldr R3, = VAL2B adds R8,R0,R1 adcs R9,R1,R3 stop b stop END
- Copy to RAM
AREA Exaddress, CODE, READONLY EXPORT Reset_Handler Reset_Handler LDR R9, =list mov R7, #4 ; number in list ldr r6, =datastart loop ldr r8,[r9],#4 str r8,[r6],#4 subs r7,r7,#1 bne loop stop b stop ALIGN list DCW 0x1111, 0x2222, 0x3333, 0x4444, 0x5555 ALIGN string DCB "This is a test.",0 ; This string is not used in the copy to ram program string2 DCB 'T','h','i' ; This string2 is not used in the copy to ram program ALIGN AREA Thedata, DATA, NOINIT, READWRITE datastart SPACE 20 END
- Subroutine Example1
; First Subroutine Example ; This program demonstrates using a subroutine, ; saving registers on the stack, etc. ; Rob Frohne, 1/3/2013 stack_start EQU 0x40001000 AREA Subroutine_Example, CODE ENTRY Start ldr sp, =stack_start ; Tell where we will place the stack. ; (It goes down (lower addresses from here.) mov r1, #1 ; Store some numebers in some registers mov r2, #2 mov r3, #3 bl subroutine stop b stop ; This subroutine saves the registers, ; messes up the registers locally, ; then restores the registers and returns. subroutine stmfd sp!, {r1-r2,lr} ; save used registers and the link register (r14) mov r1,#0xffffffff ; mess up the registers mov r2, r1 ldmfd sp!, {r1,r2,pc} ; pop the stack and return END
- Minimum of a Signed Number
; This program finds the minimum of a list of constant words in signed format ; The result is in r3 at the end of the routine. ; Rob Frohne 10/30/2013 AREA Program, CODE, READONLY ENTRY ldr r0,=end ; load the beginning address of the code & initialize it as the pointer. ldr r2,=begin ; load the ending address of the code. mov r3,#0x7fffffff ; Initialize r3 as the most positive number. loop ldr r6,[r2],#4 ; load the next data into r6 and post increment r2 for the next data. cmp r6,r3 ; Find out if r6 > r3. result from r6-r3 like subs r7,r6,r3 without r6 necessary. bgt no_update ; If it is no update. mov r3,r6 ; update if r6 is lower than r3. no_update cmp r0,r2 ; are we at the end yet bne loop ; if r7 != 0 then keep looping stop b stop ALIGN begin DCD 0x8fffffff, 0x55555555, 0x44444444, 0x77777777, 0xffffffff end END
- Compare Two Null Terminated Strings
; Subroutine to compare two null terminated ASCII strings. ; The address where the two strings start are in r0 and r1 ; The return is in r0, 1 for match and 0 for don't match. ; If they don't match, r1 gives the number of the first ; character that didn't match, starting with 0. ; r2 and r3 are not protected. ; Rob Frohne 11/6/2013 stack_start EQU 0x40001000 AREA String_Compare, CODE ENTRY Start ldr sp, =stack_start ; Tell where we will place the stack. ; (It goes down (lower addresses from here.) ldr r0, =string1 ldr r1, =string2 bl compare_strings stop b stop compare_strings stmfd sp!, {r2,r4,r5,lr} ; save used registers and the link register (r14) mov r2, #0 ; Initialize the counter for the first position. loop ldrb r4,[r0],#1 ldrb r5,[r1],#1 cmp r5,r4 bne do_not_match cmp r4, #0 ; check for end of string. beq match add r2, #1 b loop do_not_match mov r0, #0 ; don't match b finish match mov r0, #1 finish mov r1,r2 ; Move the count into the result register. ldmfd sp!, {r2,r4,r5,pc} ; pop the stack and return string1 DCB "This is the first string.",00 ; For testing purposes. ALIGN string2 DCB "This is the first string.",00 ALIGN END
- BCD Add
; Subroutine to add two BCD numbers in 32 bit form with each nibble ; representing a digit. ; locals: r8 for digit counter, mask 0xf, r5 & r6 for masked addends, ; working BCD_carry, r7 for ; working result in r4 ; inputs: r0+r1 ; outupts: r0 result and r1 carry ; only r5-r8 are saved. ; Rob Frohne 11/12/13 stack_start EQU 0x40001000 AREA String_Compare, CODE ENTRY Start ldr sp, =stack_start ; Tell where we will place the stack. ; (It goes down (lower addresses from here.) ldr r0, =0x12345678 ; The two numbers to add. ldr r1, =0x87654322 bl bcd_add stop b stop bcd_add ; The subroutine stmfd sp!, {r5-r8,lr} mov r8, #8 ; Set the counter to move through the eight digits mov r7, #0 ; Set the carry to zero to start with mov r3, #0 ; This is where the resulting digits of the sum are stored. loop and r5, r0, #0xf ; mask for the rightmost digit. and r6, r1, #0xf add r4, r5, r7 ; add carry add r4, r4, r6 ; r4=r5+r6 subs r4, r4, #10 ; Subtract 10 (base 10) to see if there is a carry. bmi no_carry mov r7, #1 ; set the carry b roll_to_next_digit no_carry mov r7, #0 ; set carry to zero add r4, r4, #10 ; Add the 10 back in as there was no carry needed. roll_to_next_digit orr r3, r3, r4 ; Add thise digits into the sum. ror r0, #4 ror r1, #4 ror r3, #4 subs r8, r8, #1 ; Decrement digit counter bne loop ; If it isn't zero do the next digit. mov r0, r3 ; Set the output registers. r0 is result. r1 is carry. mov r1, r7 ldmfd sp!, {r5-r8,pc} END