Wed. Sept 6 Announcements HW 3 / Lab 3 posted [1.C]-1
Endianness Problem: Memory is byte addressed. Sometimes you want to access multi-byte values (16-bit, 32-bits etc.) X is 2-bytes Addr Memory Value LDX $100 There is only 1-byte at address $100 99 100 101 $12 $34 $56 Q: Where does the other byte come from? Q: What is the final value loaded into X? A: 101 A: $3456 Q: Is that the ONLY possibility? [1.C]-2
Endianness X = $3456 LDX $100 Address Points to BIG byte of the number Big Endian Addr 99 100 101 Memory Value $12 $34 $56 9S12 (ECE 362) X = $5634 LDX $100 Address Points to little byte of the number Little Endian Addr 99 100 101 Memory Value $12 $34 $56 [1.C]-3
Indexed-Indirect with constant offset Review Abbrev. Name Description Examples [IDX2] Indexed-Indirect with Constant Offset X A Eff. address = ((<X Y SP PC>) + signed_const) Example Instruction LDAA [0,Y] ADDA [5,X] Memory 2 memory lookups Eff Address (H) Eff Address (L) Indirect Address + Assembly Instruction opcode postbyte offset high offset low ADDA [5,X] 1010 1011 1110 0011 0000 0000 0000 0101 [1.C]-4
Pointless Clicker Question #3 What is the result after the instruction: Review ADDA [0,X] Memory Addr Value 0 0t A: A=12t, X = 0t B: A=17t, X = 0t P C: A=21t, X = 2t D: A=21t, X = 0t E: I am too lost to try Regs Name Value A 10t 1 2t 2 7t 3 0t X 0t 65534 7t [1.C]-5
Module 1-C Assembly Control Structures Tim Rogers 2017 [1.C]-6
Learning Outcome #1 An ability to program a microcontroller to perform various tasks How? A. Architecture and Programming Model B. Instruction Set Overview C. Assembly Control Structures D. Control Structure Applications E. Table Lookup F. Parameter Passing G. Macros and Structured Programming [1.C]-7
Objective Assembly Control Structures Typically High-level lang. code Why? Compiler Eg. gcc,vscc, cw Assembly Code Right now ECE 362 Still useful to think about high-level language constructs: loops, conditionals, etc [1.C]-8
But First Some Background Pseudo Ops Tells assembler to do something without generating any code These pseudo ops are specific to each dev env These can make your assembly coding life easier and your code easier to read. [1.C]-9
Key Code Warrior Pseudo Ops Pseudo op Description Example ORG RMB EQU Originate code. Sets the memory address of the code that follows Reserve Memory Byte. Allocates (but does not initialize) memory. Equate a label with a org $800 ldaa #5 ; This instruction starts at $800 label RMB 2 ; reserve 2 bytes starting at label loopiterations EQU 5 ; Assembler will replace loopiterations with 5 numeric value FCB Form Constant Byte. value FCB 8 ; the label value points to memory initialized to 8 FDB Form Double Byte value FDB $FFFF ; the label value points to the high byte of memory initialized to $FFFF [1.C]-10
Key Code Warrior Pseudo Ops Pseudo op Description Example FCC Form Constant Character string fcc This is a string ; label string now points to the quoted text INCLUDE Include another assembly file include myfile.asm END Reserve Memory Byte. Allocates (but does not initialize) memory. ; some code end I can write whatever I want here, cause the assembler will stop looking. [1.C]-11
Expressions Can include these in the operand field of some instructions Executed on your desktop at assembly time, not on the 9S12 at runtime. Examples: ldaa #2*value/37 bne exit+1 staa mem+2 [1.C]-12
Strings Quoted strings are converted to equivalent ASCII characters by the assembler program Examples: cmpa #'J' string fcc Hello world [1.C]-13
Labels Labels are symbols used to represent memory locations in which program or data are stored When used in the operand field of a transfer-ofcontrol instruction, the assembler converts these symbols to absolute locations (for jump instructions) or signed relative offsets (for branch instructions) Examples: org $800 jmp iloop ; address is $803 iloop bra iloop ; offset is $FE [1.C]-14
Control Structures Naïve and optimized ways to transform them Roughly the equivalent of turning off/on optimizations in your compiler Naïve versions are much easier to understand and are a 1:1 translation of the original source code. [1.C]-15
IF-ELSE IF C Syntax: if (condition 1) <statement 1>; else if (condition 2) <statement 2>; else if (condition 3) <statement 3>; Example: if(i==1) pay=100; else if(i==2) pay=200; else if(i==3) pay=300; else if(i==4) pay=400; Hand Compilation: ; variables i rmb 1; pay rmb 2; ; Assume some code sets i if1 if2 if3 if4 Notice that the conditions are inverted ldaa i cmpa #1 bne if2 movw #100,pay bra if_end cmpa #2 bne if3 movw #200,pay bra if_end cmpa #3 bne if4 movw #300,pay bra if_end cmpa #4 bne if_end movw #400,pay if_end [1.C]-16
SWITCH (CASE) C Syntax: switch (variable) { } case value 1: <statement 1>; break; case value 2: <statement 2>; break; case value 3: <statement 3>; break; default: <statement default>; Example: switch(i) { case 1: pay=100; break; case 2: pay=200; break; case 3: pay=300; break; case 4: pay=400; break; default: pay=0; } Hand Compilation: ; variables i rmb 1; pay rmb 2; ; Assume some code sets i case_start ldaa i case1 cmpa #1 bne case2 movw #100,pay bra case_exit case2 cmpa #2 bne case3 movw #200,pay bra case_exit case3 cmpa #3 bne case4 movw #300,pay bra case_exit case4 cmpa #4 bne default movw #400,pay bra case_exit default movw #0,pay case_exit [1.C]-17
FOR C Syntax: for (variable initialization; condition; variable update) { <statements executed while condition is true>; } Hand Compilation: Example: unsigned int I; for(i=1;i<=10;i++) { ; } 16-bit unsigned control variable I rmb 2 for_start movw #1,I for_loop ldd I cpd #10 bhi for_exit ldd I addd #1 std I bra for_loop for_exit [1.C]-18
WHILE C Syntax: while (condition) { <statements executed while condition is true>; } Example: unsigned int I; I=1; while(i<=10) { ; I++; } 16-bit unsigned control variable Hand Compilation: I rmb 2 while_start movw #1,I while_loop ldd I cpd #10 bhi while_exit ldd I addd #1 std I bra while_loop while_exit In this while, assembly is identical to for [1.C]-19
DO WHILE C Syntax: do { <statements executed while condition is true>; } while (condition) Example: unsigned int I; I=1; do { ; I++; } while(i<=10) 16-bit unsigned control variable In do, the conditions are the same Hand Compilation: I rmb 2 dowhile_start movw #1,I dowhile_loop ldd I addd #1 std I cpd #10 bls dowhile_loop dowhile_exit [1.C]-20
Some optimized loop constructs Prof. Meyer referred to these as assembly style Need to be careful about register bounds. i.e. a loop with an 8-bit counter can only go around a limited number of times [1.C]-21
Optimized FOR (0 255) Key: Use registers as loop counters ITER EQU ; unsigned byte ( char ) calculation of ITER+1 is done at assembly time for_start ldab #ITER+1 for_loop dbeq b,for_exit bra for_loop for_exit Basic idea: Count (B) down, and use the ZERO condition as a completion indicator make use of compound decrement and branch instruction [1.C]-22
Optimized FOR (0 65,535) Key: Use registers as loop counters calculation of ITER+1 is done at assembly time ITER EQU for_start ldx #ITER+1 for_loop dbeq x,for_exit ; unsigned word ( int ) Basic idea: Count (X) down, and use the ZERO condition as a completion indicator make use of compound decrement and branch instruction bra for_loop for_exit Note: In optimized FOR constructs, the loop overhead is reduced to 3 instructions [1.C]-23
Optimized DO (1 256) ITER EQU ; unsigned byte ( char ) do_start ldab #ITER do_loop code block is executed at least once dbne b,do_loop do_exit completion check at bottom of loop [1.C]-24
Optimized DO (1 65,536) ITER EQU ; unsigned word ( int ) do_start ldx do_loop #ITER code block is executed at least once dbne x,do_loop do_exit completion check at bottom of loop Note: In optimized DO constructs, the loop overhead is reduced to 2 instructions [1.C]-25