ECE251: Tuesday September 18 Subroutine Parameter Passing (Important) Allocating Memory in Subroutines (Important) Recursive Subroutines (Good to know) Debugging Hints Programming Hints Preview of I/O (GPIO) as Time Allows Labs: #4 starts next week. Prework as always Homework: #3 due next Thursday, Sept. 27 Mid-Term Exam on October 4, week after next. Lab Practical #1 week of October 9 in lab. 1
But First, A Message From Lab #9! Another Interesting Project ST77735 SPI 128x160 TFT LCD Display Interfaced to TIVA Board in C Also Interfaced to Arduino Convert this to library callable by our Assembly Language Routines 1 or 2-person project. See me. 2
Stacks, PUSH, and POP PUSHes and POPs must be balanced and in opposite orders at subroutine level E.g. PUSH {Ra}, Allocate_30_words must be followed by Deallocate_30_words, POP {Rb} Otherwise higher level routines would not have the stack pointing to the right information after a subroutine exit (BX LR) One of the reasons these structures are called stacks, like stacking and unstacking plates. Unstacking occurs in exact opposite order of stacking. 3
Subroutines: Parameter Passing (8.4.1) Call by Value: Sends parameter VALUES (i.e. numbers) directly to/from subroutine These values can be in registers or the stack They have nothing to do with memory addresses Just give me the facts, ma am Don t need no stinkin addresses Call by Reference: Sends parameter value ADDRESSES to/from subroutine These addresses can be in registers or on the stack The content of these address is not passed directly 4
Call by Value: Swap Routine Label Op-Code Operand(s) Comment SWAP PUSH PUSH POP POP BX LR {R1} {R2} {R1} {R2} Is this a valid Subroutine? Why or why not? Where are the parameters when SWAP is called? Why are they Call by Value? 5
Call by Reference: Copy Array of Bytes Routine to copy array of bytes to a second area COPY Test CMP r0,#0 ; r0 is counter-test for 0 BXEQ LR ;Return if counter is 0 LDRB r3, [r1],#1 ;r3=[r1] r1=r1+1 (byte) STRB r3, [r2],#1 ;r3=[r2] r2=r2+1 (byte) SUB r0, #1 ;decrement counter B Test ;retry loop What are the subroutine s parameters? Which are call by reference? Why? How short can the copied array be? How long? How would we modify this to copy array of WORDS? What kind of loop is this (While,Until,For,...) 6
Subroutine Parameters and Memory Allocation Parameter passing: These are all valid methods - Use registers - Use the stack - Use global memory, i.e. any addresses with data you have defined Returning results: These are all valid methods - Use registers - Use the stack (We can create a location where the result will be placed) - Use global memory LOCAL VARIABLE ALLOCATION (ONLY by subroutine) - Allocated by the callee (called subroutine, not caller) - The following instruction efficiently allocates local variables: SUB SP, #40 ; allocate? words in the stack Local variable deallocation - Performed by the subroutine - Must always be done before subroutine exits. Why? - The following instruction efficiently deallocates local variables: ADD SP, #40 ; deallocate? words from the stack 7
Stack Frame - The region in the stack that holds subroutine parameters, the subroutine return address, local variables, and saved registers is referred to as the stack frame. - The stack frame is also called activation record, because it is a block of memory which is activated when a subroutine is called. SP after SUB SUB SP,#40 SP before SUB DECREASING Memory Local variables Saved registers Save return address Subroutine Incoming and Outgoing parameters Stack Stack Frame: Part created by called subroutine itself Part created by calling program 8
Stack Frame Look a little more at incoming and outgoing parameters That s where results go if they are in the stack (vs. registers or global memory Just like incoming parameters, outgoing parameters (return info to caller) must have space set aside by the calling program. Why? Local variables Saved registers Stack Frame: Part created by called subroutine itself What software creates the space for these outgoing parameters? Save return address Subroutine Incoming and Outgoing parameters Stack Part created by calling program 9
Accessing Parameters in the Stack Frame It s easy--just use normal indexing with SP. Offset will always be positive. Why? SP after SUB SR,#40 e.g. LDR r0,[sp,#20] Local variables Saved registers Created by Called Subroutine Save return address Incoming and outgoing parameters Stack 10
Accessing Local Variables in the Stack Frame It s not too hard--just use normal indexing with SP, like local variables. The challenge is computing the offset, which the programmer must do. You can equate the offset number to a label, making understanding of the program a little easier. E.g. STR ro, [SP,#Maxval] SP after SUB SR,#40 Local variables Saved registers Created by Called Subroutine e.g. LDR r0,[sp,#52] or STR r0,[sp,#52] Save return address Incoming and outgoing parameters Part created by calling program Stack 11
Recursive Functions A recursive function is one that solves its task by calling itself on smaller pieces of data. Recursive functions are good at showing how stack is used An effective tactic is to divide a problem into sub-problems of the same type as the original, solve those sub-problems, and combine the results 12
Defining Factorial(n) Product of the first n numbers 1 2 3 n factorial(0) = 1 factorial(1) = 1 factorial(2) = 2 1 factorial(3) = 3 2 1 factorial(4) = 4 3 2 1 factorial(n) = n (n-1) 1 = 1 factorial(0) = 2 factorial(1) = 3 factorial(2) = 4 factorial(3) = n factorial(n-1) 13
Classic Recursion Example: Factorial Factorial is the classic educational example: 6! = 6 5! = 6 5 x 4! = 6 5 x 4 x 3! 6! = 6 5 4 3 2 1 The factorial function can be written as a recursive function: ; Input: r0 is n ; Output: r0 is Fact(n) ; A bit hard to follow? Recursive functions often are! FACT CMP r0, #1 ;Is n <= 1? BLE ENDC ;If so, to ENDC PUSH {r0,lr} ;Save r0 (n) and lr on TOS SUB r0, r0, #1 ;n=n=1 BL FACT ;get FACT(n-1) in r0 POP {r1, lr} ;restore r1 (n), lr from TOS MUL r0, r1, r0 ;r0=n*fact(n-1) BX LR ;normal return ENDC MOV r0, #1 ;r0=fact(1)=1 BX LR ;end case return 14
Factorial Parameters Input to FACT is in r0, call by value Output is in r0, returns value Temporary n stored in stack as a value Try this by hand with input r0=3. I.e. compute 3! ; Input: r0 is n ; Output: r0 is Fact(n) ; A bit hard to follow? Recursive functions often are FACT CMP r0, #1 ;Is n <= 1? BLE ENDC ;If so, to ENDC PUSH {r0,lr} ;Save r0 (n) and lr on TOS SUB r0, r0, #1 ;n=n=1 BL FACT ;get FACT(n-1) in r0 POP {r1, lr] ;restore r1 (n), lr from TOS MUL r0, r1, r0 ;r0=n*fact(n-1) BX LR ;normal return ENDC MOV r0, #1 ;r0=fact(1)=1 BX LR ;end case return 15
Classic Example: Fibonacci Numbers f(n) = f(n-1) + f(n-2) f(0) = 0 f(1) = 1 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, How might we modify Factorial function to perform this function recursively? How would we write a program to compute Fibonacci series non-recursively? Would we need to store the entire series up to the number we re computing? 16
Analysis of fib(5) 5 fib(5) fib(4) 3 2 fib(3) 2 1 1 1 fib(3) fib(2) fib(2) fib(1) 1 1 1 0 1 0 fib(2) fib(1) fib(1) fib(0) fib(1) fib(0) 1 fib(1) 0 fib(0) 17
Recursion vs Iteration Any problem that can be solved recursively (calls itself) can also be solved iteratively (using loop). Recursive functions (vs. Iterative functions) Cons: Recursive functions are slow Recursive function take more memory Pros Recursive functions resembles the problem more naturally Recursive functions may be easier to program and debug IF the function is CAREFULLY created as recursive (see next slide) Try drawing a flow chart for an iterative function to compute a Fibonacci value to determine which is more natural 18
Recursive Functions PUSH LR (& working registers) onto stack before nested call POP LR (& working registers) off stack after nested return Just like any other nested subroutine calls 19
We are NOT going to go over the next 18 slides in detail! We will review them briefly to see how the stack is used in recursive subroutines. They are available to you to look at the details of subroutine calls, stack usage, and computation to compute a factorial. There are easier ways to do this! 20
Recursive Factorial in Assembly AREA main, CODE, READONLY EXPORT main ENTRY 0x08000130 0x08000136 0x08000138 0x0800013A 0x0800013C 0x0800013E 0x08000140 0x08000142 0x08000144 0x0800014C main PROC MOV r0, #0x03 stop B stop ENDP factorial PUSH {r4, lr} MOV r4, r0 CMP r4, #0x01 BNE NZ MOVS r0, #0x01 loop POP {r4, pc} NZ SUBS r0, r4, #1 MUL r0, r4, r0 B loop return 6 3 * factorial(2) return 2 2 * factorial(1) 1 Note implied BX LR instruction! END 21
Recursive Factorial in Assembly 0x08000130 0x08000136 0x08000138 0x0800013A 0x0800013C 0x0800013E 0x08000140 0x08000142 0x08000144 0x0800014C AREA main, CODE, READONLY EXPORT main ENTRY main MOV r0, #0x03 stop B stop factorial PUSH {r4, lr} MOV r4, r0 CMP r4, #0x01 BNE NZ MOVS r0, #0x01 loop POP {r4, pc} NZ SUBS r0, r4, #1 MUL r0, r4, r0 B loop END 0x08000130 0xFFFFFFFF 0x20000600 0 3 pc lr sp r4 r0 Data Address 0x12345678 Memory 0xFFFFFFFF 0x20000600 0x200005FC 0x200005F4 0x200005EC 0x200005E8 0x200005E4 0x200005E0 0x200005DC 0x200005D8 0x200005D4 0x00000000 22
Recursive Factorial in Assembly 0x08000130 0x08000136 0x08000138 0x0800013A 0x0800013C 0x0800013E 0x08000140 0x08000142 0x08000144 0x0800014C AREA main, CODE, READONLY EXPORT main ENTRY main PROC MOV r0, #0x03 stop B stop ENDP factorial PUSH {r4, lr} MOV r4, r0 CMP r4, #0x01 BNE NZ MOVS r0, #0x01 loop POP {r4, pc} NZ SUBS r0, r4, #1 MUL r0, r4, r0 B loop END 0x08000136 0x20000600 0 3 pc lr sp r4 r0 Data Address 0x12345678 Memory 0xFFFFFFFF 0x20000600 0x200005FC 0x200005F4 0x200005EC 0x200005E8 0x200005E4 0x200005E0 0x200005DC 0x200005D8 0x200005D4 0x00000000 23
Recursive Factorial in Assembly 0x08000130 0x08000136 0x08000138 0x0800013A 0x0800013C 0x0800013E 0x08000140 0x08000142 0x08000144 0x0800014C AREA main, CODE, READONLY EXPORT main ENTRY main PROC MOV r0, #0x03 stop B stop ENDP factorial PUSH {r4, lr} MOV r4, r0 CMP r4, #0x01 BNE NZ MOVS r0, #0x01 loop POP {r4, pc} NZ SUBS r0, r4, #1 MUL r0, r4, r0 B loop END 0x08000138 3 3 Order in which registers are specified is not important: the lowest register is always stored at the lowest address pc lr sp r4 r0 Data Address 0x12345678 0 Memory 0xFFFFFFFF 0x20000600 0x200005FC 0x200005F4 0x200005EC 0x200005E8 0x200005E4 0x200005E0 0x200005DC 0x200005D8 0x200005D4 0x00000000 24
Recursive Factorial in Assembly 0x08000130 0x08000136 0x08000138 0x0800013A 0x0800013C 0x0800013E 0x08000140 0x08000142 0x08000144 0x0800014C AREA main, CODE, READONLY EXPORT main ENTRY main PROC MOV r0, #0x03 stop B stop ENDP factorial PUSH {r4, lr} MOV r4, r0 CMP r4, #0x01 BNE NZ MOVS r0, #0x01 loop POP {r4, pc} NZ SUBS r0, r4, #1 MUL r0, r4, r0 B loop END 0x08000144 3 2 pc lr sp r4 r0 Data Address 0x12345678 0 Memory 0xFFFFFFFF 0x20000600 0x200005FC 0x200005F4 0x200005EC 0x200005E8 0x200005E4 0x200005E0 0x200005DC 0x200005D8 0x200005D4 0x00000000 25
Recursive Factorial in Assembly 0x08000130 0x08000136 0x08000138 0x0800013A 0x0800013C 0x0800013E 0x08000140 0x08000142 0x08000144 0x0800014C AREA main, CODE, READONLY EXPORT main ENTRY main PROC MOV r0, #0x03 stop B stop ENDP factorial PUSH {r4, lr} MOV r4, r0 CMP r4, #0x01 BNE NZ MOVS r0, #0x01 loop POP {r4, pc} NZ SUBS r0, r4, #1 MUL r0, r4, r0 B loop END 0x08000136 3 2 pc lr sp r4 r0 Data Address 0x12345678 0 Memory 0xFFFFFFFF 0x20000600 0x200005FC 0x200005F4 0x200005EC 0x200005E8 0x200005E4 0x200005E0 0x200005DC 0x200005D8 0x200005D4 0x00000000 26
Recursive Factorial in Assembly 0x08000130 0x08000136 0x08000138 0x0800013A 0x0800013C 0x0800013E 0x08000140 0x08000142 0x08000144 0x0800014C AREA main, CODE, READONLY EXPORT main ENTRY main PROC MOV r0, #0x03 stop B stop ENDP factorial PUSH {r4, lr} MOV r4, r0 CMP r4, #0x01 BNE NZ MOVS r0, #0x01 loop POP {r4, pc} NZ SUBS r0, r4, #1 MUL r0, r4, r0 B loop END 0x08000138 2 2 pc lr sp r4 r0 Data Address 0x12345678 0 3 Memory 0xFFFFFFFF 0x20000600 0x200005FC 0x200005F4 0x200005EC 0x200005E8 0x200005E4 0x200005E0 0x200005DC 0x200005D8 0x200005D4 0x00000000 27
Recursive Factorial in Assembly 0x08000130 0x08000136 0x08000138 0x0800013A 0x0800013C 0x0800013E 0x08000140 0x08000142 0x08000144 0x0800014C AREA main, CODE, READONLY EXPORT main ENTRY main PROC MOV r0, #0x03 stop B stop ENDP factorial PUSH {r4, lr} MOV r4, r0 CMP r4, #0x01 BNE NZ MOVS r0, #0x01 loop POP {r4, pc} NZ SUBS r0, r4, #1 MUL r0, r4, r0 B loop END 0x08000144 2 1 pc lr sp r4 r0 Data Address 0x12345678 0 3 Memory 0xFFFFFFFF 0x20000600 0x200005FC 0x200005F4 0x200005EC 0x200005E8 0x200005E4 0x200005E0 0x200005DC 0x200005D8 0x200005D4 0x00000000 28
Recursive Factorial in Assembly 0x08000130 0x08000136 0x08000138 0x0800013A 0x0800013C 0x0800013E 0x08000140 0x08000142 0x08000144 0x0800014C AREA main, CODE, READONLY EXPORT main ENTRY main PROC MOV r0, #0x03 stop B stop ENDP factorial PUSH {r4, lr} MOV r4, r0 CMP r4, #0x01 BNE NZ MOVS r0, #0x01 loop POP {r4, pc} NZ SUBS r0, r4, #1 MUL r0, r4, r0 B loop END 0x08000136 2 1 pc lr sp r4 r0 Data Address 0x12345678 0 3 Memory 0xFFFFFFFF 0x20000600 0x200005FC 0x200005F4 0x200005EC 0x200005E8 0x200005E4 0x200005E0 0x200005DC 0x200005D8 0x200005D4 0x00000000 29
Recursive Factorial in Assembly 0x08000130 0x08000136 0x08000138 0x0800013A 0x0800013C 0x0800013E 0x08000140 0x08000142 0x08000144 0x0800014C AREA main, CODE, READONLY EXPORT main ENTRY main PROC MOV r0, #0x03 stop B stop ENDP factorial PUSH {r4, lr} MOV r4, r0 CMP r4, #0x01 BNE NZ MOVS r0, #0x01 loop POP {r4, pc} NZ SUBS r0, r4, #1 MUL r0, r4, r0 B loop END 0x08000138 0x200005E8 1 1 pc lr sp r4 r0 Data Address 0x12345678 0 3 2 Memory 0xFFFFFFFF 0x20000600 0x200005FC 0x200005F4 0x200005EC 0x200005E8 0x200005E4 0x200005E0 0x200005DC 0x200005D8 0x200005D4 0x00000000 30
Recursive Factorial in Assembly 0x08000130 0x08000136 0x08000138 0x0800013A 0x0800013C 0x0800013E 0x08000140 0x08000142 0x08000144 0x0800014C AREA main, CODE, READONLY EXPORT main ENTRY main PROC MOV r0, #0x03 stop B stop ENDP factorial PUSH {r4, lr} MOV r4, r0 CMP r4, #0x01 BNE NZ MOVS r0, #0x01 loop POP {r4, pc} NZ SUBS r0, r4, #1 MUL r0, r4, r0 B loop END 0x0800013E 0x200005E8 1 1 pc lr sp r4 r0 Data Address 0x12345678 0 3 2 Memory 0xFFFFFFFF 0x20000600 0x200005FC 0x200005F4 0x200005EC 0x200005E8 0x200005E4 0x200005E0 0x200005DC 0x200005D8 0x200005D4 0x00000000 31
Recursive Factorial in Assembly 0x08000130 0x08000136 0x08000138 0x0800013A 0x0800013C 0x0800013E 0x08000140 0x08000142 0x08000144 0x0800014C AREA main, CODE, READONLY EXPORT main ENTRY main PROC MOV r0, #0x03 stop B stop ENDP factorial PUSH {r4, lr} MOV r4, r0 CMP r4, #0x01 BNE NZ MOVS r0, #0x01 loop POP {r4, pc} NZ SUBS r0, r4, #1 MUL r0, r4, r0 B loop END 2 1 pc lr sp r4 r0 Data Address 0x12345678 0 3 Memory 0xFFFFFFFF 0x20000600 0x200005FC 0x200005F4 0x200005EC 0x200005E8 0x200005E4 0x200005E0 0x200005DC 0x200005D8 0x200005D4 0x00000000 32
Recursive Factorial in Assembly 0x08000130 0x08000136 0x08000138 0x0800013A 0x0800013C 0x0800013E 0x08000140 0x08000142 0x08000144 0x0800014C AREA main, CODE, READONLY EXPORT main ENTRY main PROC MOV r0, #0x03 stop B stop ENDP factorial PUSH {r4, lr} MOV r4, r0 CMP r4, #0x01 BNE NZ MOVS r0, #0x01 loop POP {r4, pc} NZ SUBS r0, r4, #1 MUL r0, r4, r0 B loop END 2 2 pc lr sp r4 r0 Data Address 0x12345678 0 3 Memory 0xFFFFFFFF 0x20000600 0x200005FC 0x200005F4 0x200005EC 0x200005E8 0x200005E4 0x200005E0 0x200005DC 0x200005D8 0x200005D4 0x00000000 33
Recursive Factorial in Assembly 0x08000130 0x08000136 0x08000138 0x0800013A 0x0800013C 0x0800013E 0x08000140 0x08000142 0x08000144 0x0800014C AREA main, CODE, READONLY EXPORT main ENTRY main PROC MOV r0, #0x03 stop B stop ENDP factorial PUSH {r4, lr} MOV r4, r0 CMP r4, #0x01 BNE NZ MOVS r0, #0x01 loop POP {r4, pc} NZ SUBS r0, r4, #1 MUL r0, r4, r0 B loop END 0x08000140 Order in which registers are specified is not important. 2 2 pc lr sp r4 r0 Data Address 0x12345678 0 3 Memory 0xFFFFFFFF 0x20000600 0x200005FC 0x200005F4 0x200005EC 0x200005E8 0x200005E4 0x200005E0 0x200005DC 0x200005D8 0x200005D4 0x00000000 34
Recursive Factorial in Assembly 0x08000130 0x08000136 0x08000138 0x0800013A 0x0800013C 0x0800013E 0x08000140 0x08000142 0x08000144 0x0800014C AREA main, CODE, READONLY EXPORT main ENTRY main PROC MOV r0, #0x03 stop B stop ENDP factorial PUSH {r4, lr} MOV r4, r0 CMP r4, #0x01 BNE NZ MOVS r0, #0x01 loop POP {r4, pc} NZ SUBS r0, r4, #1 MUL r0, r4, r0 B loop END 3 2 pc lr sp r4 r0 Data Address 0x12345678 0 Memory 0xFFFFFFFF 0x20000600 0x200005FC 0x200005F4 0x200005EC 0x200005E8 0x200005E4 0x200005E0 0x200005DC 0x200005D8 0x200005D4 0x00000000 35
Recursive Factorial in Assembly 0x08000130 0x08000136 0x08000138 0x0800013A 0x0800013C 0x0800013E 0x08000140 0x08000142 0x08000144 0x0800014C AREA main, CODE, READONLY EXPORT main ENTRY main PROC MOV r0, #0x03 stop B stop ENDP factorial PUSH {r4, lr} MOV r4, r0 CMP r4, #0x01 BNE NZ MOVS r0, #0x01 loop POP {r4, pc} NZ SUBS r0, r4, #1 MUL r0, r4, r0 B loop END 3 6 pc lr sp r4 r0 Data Address 0x12345678 0 Memory 0xFFFFFFFF 0x20000600 0x200005FC 0x200005F4 0x200005EC 0x200005E8 0x200005E4 0x200005E0 0x200005DC 0x200005D8 0x200005D4 0x00000000 36
Recursive Factorial in Assembly 0x08000130 0x08000136 0x08000138 0x0800013A 0x0800013C 0x0800013E 0x08000140 0x08000142 0x08000144 0x0800014C AREA main, CODE, READONLY EXPORT main ENTRY main PROC MOV r0, #0x03 stop B stop ENDP factorial PUSH {r4, lr} MOV r4, r0 CMP r4, #0x01 BNE NZ MOVS r0, #0x01 loop POP {r4, pc} NZ SUBS r0, r4, #1 MUL r0, r4, r0 B loop END 3 6 pc lr sp r4 r0 Data Address 0x12345678 0 Memory 0xFFFFFFFF 0x20000600 0x200005FC 0x200005F4 0x200005EC 0x200005E8 0x200005E4 0x200005E0 0x200005DC 0x200005D8 0x200005D4 0x00000000 37
Recursive Factorial in Assembly 0x08000130 0x08000136 0x08000138 0x0800013A 0x0800013C 0x0800013E 0x08000140 0x08000142 0x08000144 0x0800014C AREA main, CODE, READONLY EXPORT main ENTRY main PROC MOV r0, #0x03 stop B stop ENDP factorial PUSH {r4, lr} MOV r4, r0 CMP r4, #0x01 BNE NZ MOVS r0, #0x01 loop POP {r4, pc} NZ SUBS r0, r4, #1 MUL r0, r4, r0 B loop END 0x20000600 0 6 pc lr sp r4 r0 Data Address 0x12345678 Memory 0xFFFFFFFF 0x20000600 0x200005FC 0x200005F4 0x200005EC 0x200005E8 0x200005E4 0x200005E0 0x200005DC 0x200005D8 0x200005D4 0x00000000 38
Recursive Factorial in Assembly 0x08000130 0x08000136 0x08000138 0x0800013A 0x0800013C 0x0800013E 0x08000140 0x08000142 0x08000144 0x0800014C AREA main, CODE, READONLY EXPORT main ENTRY main PROC MOV r0, #0x03 stop B stop ENDP factorial PUSH {r4, lr} MOV r4, r0 CMP r4, #0x01 BNE NZ MOVS r0, #0x01 loop POP {r4, pc} NZ SUBS r0, r4, #1 MUL r0, r4, r0 B loop END 0x20000600 0 6 pc lr sp r4 r0 Data Address 0x12345678 Memory 0xFFFFFFFF 0x20000600 0x200005FC 0x200005F4 0x200005EC 0x200005E8 0x200005E4 0x200005E0 0x200005DC 0x200005D8 0x200005D4 0x00000000 39
Finished Topic of Stack & Subroutines Any Questions? Basic topic of HW #3 Will certainly be on Mid-Term Exam! Next lecture is on new topic: General Purpose or Parallel I/O Read Chapter 14 in text 40
Debugging Hardware If your system isn t working: Replace the TM4C board with a known working board. If the system now works, you had a defective board. If not: Change out ONE thing from non-working system e.g. the USB cable. Reboot board, reload.o file, reset board, rerun program in an identical manner to previously. If system doesn t work, there s a problem with your USB cable. If it does work, your USB cable is OK. Do same process with another part. Result will tell you if it s working or not. Replace any offending parts. Problem should be fixed. If not, the non-working system is now working! 41
Debugging Software Begin with a known, hardware working system (see previous slide) Be sure your program ends with a deadloop, so it doesn t run off a cliff when done and change program and data area on your board. Don t expect that by just running the same program again, it will give same answer UNLESS all program and data storage has been restored and board is reset. If you re getting wrong or no answers, you need to single step your program from the start, observing all changes in register and memory data values. Also note whether program area has somehow been changed. This should be obvious if program does weird things when stepped. 42
Debugging Software-cont d During single stepping, if you see that the results are different from your expectations, figure out what s wrong with your expectations* about what should be happening. The problem is almost certainly there. This means you to need to change your program, reassemble, reset and reload board and rerun single step again to assure it s now doing the right thing at the point you had problems with earlier. Continue this process throughout the program until you get to the end with nothing different than you expected, i.e. your program executed correctly. * If you don t know what to expect after each instruction, then THAT is your primary problem. 43
Tips for Writing Programs - Review Data and Data Structures are Key Think about how data will be stored in memory Draw a picture or diagram Processing Algorithm is Key Think about how to process data Draw a FLOWCHART Break Problem into manageable chunks One page or less if several branches Two pages if mostly in-line code Use helpful names rather than numbers for values (EQU). 44
Next Lecture I/O: 2/3 of course(important) General Purpose I/O aka GPIO aka Parallel I/O Read Chapter 14 in text GPIO is Fair Game on Mid-Term Exam! It will/would be minor in point contribution It will/would be broad vs. detailed See sample exam online (coming soon) 45
Stack Usage Example ; Main Program Test Program to exercise subroutine Smart ; Assume SP Initialized to 0x20000.0600 AREA mydata, DATA Array SPACE 0x100 ; Starts at 0x2000.0000 ASSUME ALL BYTES=0xFF Var1 DCW 0x12AB ; Assume initialized AREA myprog, CODE EXPORT main main ; Start of program LDR R1, =Array ; Get parameter address LDR R0, =Var1 ; Get second parameter address LDRB R2, [R0] ; Put the call-by-value data in R2 PUSH {R1,R2} ; Push R2 and then R1 onto stack SUB SP, #4 ; Make ROOM for return data BL Smart ; Call subroutine Smart Callret NOP ; Smart returns to here ; Undo stack changes, restore registers in main program Deadl B Deadl ; Done ; Smart PUSH {R1} ; Save R1 on stack SUB SP, #8 ; Create local storage LDRB R1, [SP, #CBV] ; Fetch call-by-value data from stack ADD R1, R1, #1 ; Increment it STR R1, [SP, #ROOM] ; Put Data where ROOM was made above ; Undo all local storage created in subroutine Smart BX LR ; BX to LR address 46
Stack Usage Example a. What actual code would be used to replace the commented line: ; Undo stack changes, restore registers in main program b. On the next (opposing) page, fill in the registers and memory table with hex values where memory values are defined, and show (to left of table) where pointer SP points when the processor reaches the location commented with. If a value can t be determined, leave it blank. If it is the address of an instruction, use its label (Deadl, etc.). In addition, to the right side of the memory map show where (i.e. annotate) (1) incoming and return parameters, (2) saved registers, (from any subroutine calls) and (3) local storage (in any subroutines) are stored. c. What should the values of CBV and ROOM be, to make the instructions with operate properly? CBV EQU ROOM EQU 47
Show SP Memory Value Annotation area: below or Register (Word or Byte) R0 R1 R2 SP LR 0x20000600 SP initialized to this addr. 0x200005FF 0x200005FE 0x200005FD 0x200005FC 0x200005FB 0x200005FA 0x200005F9 0x200005F7 0x200005F6 0x200005F5 0x200005F4 0x200005F3 0x200005F2 0x200005F1 0x200005EF 0x200005EE 0x200005ED 0x200005EC 0x200005EB 0x200005EA 0x200005E9 0x200005E8 0x200005E7 48