; 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
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
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
string2 DCB 'T','h','i'
ALIGN
AREA Thedata, DATA, NOINIT, READWRITE
datastart SPACE 20
END
; 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 (Note: this is not tested. It may or may not work.)
; 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!, {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
ldmfd sp!, {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 second string.",00
ALIGN
END