Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- .global _start
- /* PseudoRandom number Generator
- This pseudo random number generator takes the 4th byte from the linux gettime(2) syscall
- which is the time in microseconds from epotch. This will then load the number into
- r1, which then subtracts from the number until it's an integer less than 10 but greater than 0.
- This subtraction is my poor mans attempt at some kind of modulus or floor operator without getting
- overly complicated as I only need to print 1 digit.
- The result of the "fakemod" will then be fed into into an algorithm to convert
- the integer as an ascii string for output.
- The period doesn't print at the end, but everything works.
- Was constrained in terms of not being allowed to use urandom, use of urandom would not have been marked by the professor.
- */
- _start:
- MOV r5, #0
- Numberloop:
- ADD r5, r5, #1 @r5 is my counter
- PUSH {r5}
- BL timeofday @grab our random number, return in r1
- BL fakemod @perform a (fake) mod operation, return in r1
- BL _numtoString
- LDR r1, =numstr
- BL _sPrint
- LDR r1, =comma
- BL _sPrint
- POP {r5}
- CMP r5, #9
- BNE Numberloop
- BEQ lasttask
- lasttask:
- BL timeofday @grab our random number, return in r1
- BL fakemod @perform a (fake) mod operation, return in r1
- BL _numtoString
- LDR r1, =numstr
- BL _sPrint
- @ This is here for testing purposes, originally _sPrint was a seperate library file in .o provided by the professor
- @ I had to disassemble the object file to extract _sPrint, _strLen, and findEnd so to avoid having to give out
- @ the object file. Nothing about the code behaviour has changed. A period is still not printed at the end.
- @This was to see if maybe the _sPrint function being used in the object file might have been the reason for the missing period.
- @As at the time I did not have it disassembled
- MOV r7, #4 @set the write bit (4) in register 7 to write to console
- MOV r0, #1 @set WRITE destination to STDOUT (terminal)
- LDR r1, =period @Loads data store at the address ID'd by the label, into r1 for output
- MOV r2, #2 @Set R2 to be the max size output prompt.
- SWI 0 @RUN/EXECUTE WRITE syscall
- @missing newline printing, commented it out for testing.
- @LDR r1 =newline
- @BL _sPrint
- B _exit
- @functions here
- timeofday:
- MOV r7, #78 @gettimeofday returns time
- LDR r0, =time @address of holder for time_t
- MOV r1, #0 @timezone not needed
- SWI #0
- LDR r0, =time @set r0 back to label addr
- LDRB r1, [r0, #4] @load epotch value from r0 into r1
- MOV PC, LR @back to calling location
- fakemod:
- CMP r1, #10 @Ensuring we don't create a negative
- SUBGE r1, r1, #10 @decrease r1 by 10 until it's a single digit
- CMP r1, #10
- BGE fakemod @if the number in r1 is still greater than 10 loop
- MOV PC, LR @once it's an integer less than 10, go back to calling enviroment
- _numtoString:
- ADD r1, r1, #48 @coverts an integer to an ascii value
- LDR r4, =numstr @loads the numstr pointer address to r4
- STR r1, [r4] @stores the Ascii integer representation into the numstr address
- MOV PC, LR @so back to the BL that called this function
- _sPrint:
- mov r0, #1 @sets r0 to 1 for printing
- push {r0, r1, lr} @saves r0,r1 and lr before branching to _strlen
- bl _strLen
- pop {r0, r1, lr} @restores the saved register
- mov r7, #4 @sets output to console
- SWI 0 @execute syscall
- mov pc, lr @back to call enviroment
- _strLen:
- mov r2, #0 @r2 is the counter
- findEnd:
- ldrb r0, [r1], #1 @load a value from r1 into r0 and increment r1 address offset
- add r2, r2, #1 @increment counter
- cmp r0, #0 @compare to 0, end of string
- bne findEnd @if not 0, loopback
- sub r2, r2, #1 @subtract 1 so we're not one step ahead of desire pointer location
- mov pc, lr
- _exit:
- MOV r7, #1
- SWI #0
- .data
- time: .space 8
- comma: .asciz ", "
- newline: .asciz "\n"
- numstr: .asciz " "
- period: .ascii ".\n"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement