Wed. Sept 6 Announcements HW 3 / Lab 3 posted
Endianness Problem: Memory is byte addressed. Sometimes you want to access multi-byte values (16-bit, 32-bits etc….) Memory X is 2-bytes Addr Value 99 $12 LDX $100 There is only 1-byte at address $100 100 $34 101 $56 Q: Where does the other byte come from? Q: What is the final value loaded into X? Q: Is that the ONLY possibility? A: 101 A: $3456
Endianness Big Endian Little Endian Addr Value Addr Value X = $3456 Memory Addr Value Memory Addr Value X = $3456 X = $5634 99 $12 LDX $100 99 $12 100 $34 LDX $100 100 $34 101 $56 Address Points to BIG byte of the number 101 $56 Address Points to little byte of the number 9S12 (ECE 362)
Indexed-Indirect with constant offset Review Abbrev. Name Description Examples [IDX2] Indexed-Indirect with Constant Offset Eff. address = ((<X|Y|SP|PC>) + signed_const) LDAA [0,Y] ADDA [5,X] X A Example Instruction Memory Assembly Instruction opcode post-byte offset high offset low ADDA [5,X] 1010 1011 1110 0011 0000 0000 0000 0101 2 memory lookups Indirect Address + Eff Address (H) Eff Address (L)
‘Pointless’ Clicker Question #3 Memory Addr Value Review What is the result after the instruction: ADDA [0,X] A: A=12t, X = 0t B: A=17t, X = 0t C: A=21t, X = 2t D: A=21t, X = 0t E: I am too lost to try… What is the result after the instruction: ADDA [0,X] A: A=12t, X = 0t B: A=17t, X = 0t C: A=21t, X = 2t D: A=21t, X = 0t E: I am too lost to try… 0t 1 2t 2 7t 3 0t Regs Name Value A 10t X 0t 65534 7t
Assembly Control Structures Module 1-C Assembly Control Structures Tim Rogers 2017
Learning Outcome #1 Architecture and Programming Model “An ability to program a microcontroller to perform various tasks” Architecture and Programming Model Instruction Set Overview Assembly Control Structures Control Structure Applications Table Lookup Parameter Passing Macros and Structured Programming How?
Objective Why? Assembly Code High-level lang. code Compiler “Assembly Control Structures” Why? Typically Assembly Code High-level lang. code Compiler Eg. gcc,vscc, cw Right now Still useful to think about high-level language constructs: loops, conditionals, etc… ECE 362
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.
Key Code Warrior Pseudo Ops Description Example ORG Originate code. Sets the memory address of the code that follows org $800 ldaa #5 ; This instruction starts at $800 RMB Reserve Memory Byte. Allocates (but does not initialize) memory. label RMB 2 ; reserve 2 bytes starting at label EQU Equate a label with a numeric value loopIterations EQU 5 ; Assembler will replace loopIterations with 5 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
Key Code Warrior Pseudo Ops 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.
Expressions Examples: ldaa #2value/37 bne exit+1 staa mem+2 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 #2value/37 bne exit+1 staa mem+2
Strings Quoted strings are converted to equivalent ASCII characters by the assembler program Examples: cmpa #'J' string fcc “Hello world”
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-of- control 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
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.
Notice that the conditions are inverted IF-ELSE IF Hand Compilation: ; “variables” i rmb 1; pay rmb 2; ; Assume some code sets i ldaa i if1 cmpa #1 bne if2 movw #100,pay bra if_end if2 cmpa #2 bne if3 movw #200,pay if3 cmpa #3 bne if4 movw #300,pay if4 cmpa #4 bne if_end movw #400,pay if_end 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;
SWITCH (CASE) Example: C Syntax: switch(i) { switch (variable) { 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 case3 cmpa #3 bne case4 movw #300,pay case4 cmpa #4 bne default movw #400,pay default movw #0,pay case_exit SWITCH (CASE) Example: switch(i) { case 1: pay=100; break; case 2: pay=200; case 3: pay=300; case 4: pay=400; default: pay=0; } C Syntax: switch (variable) { case value 1: <statement 1>; break; case value 2: <statement 2>; case value 3: <statement 3>; default: <statement default>; }
FOR 16-bit unsigned control variable C Syntax: for (variable initialization; condition; variable update) { <statements executed while condition is true>; } Hand Compilation: I rmb 2 for_start movw #1,I for_loop ldd I cpd #10 bhi for_exit <statements> addd #1 std I bra for_loop for_exit Example: unsigned int I; for(I=1;I<=10;I++) { <statements>; } 16-bit unsigned control variable
assembly is identical to for WHILE C Syntax: while (condition) { <statements executed while condition is true>; } In this while, assembly is identical to for Hand Compilation: I rmb 2 while_start movw #1,I while_loop ldd I cpd #10 bhi while_exit <statements> addd #1 std I bra while_loop while_exit Example: unsigned int I; I=1; while(I<=10) { <statements>; I++; } 16-bit unsigned control variable
In do, the conditions are the same DO WHILE C Syntax: do { <statements executed while condition is true>; } while (condition) Hand Compilation: I rmb 2 dowhile_start movw #1,I dowhile_loop <statements> ldd I addd #1 std I cpd #10 bls dowhile_loop dowhile_exit Example: unsigned int I; I=1; do { <statements>; I++; } while(I<=10) 16-bit unsigned control variable In do, the conditions are the same
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
“Optimized” FOR (0 – 255) Key: Use registers as loop counters ITER EQU ___ ; unsigned byte (“char”) for_start ldab #ITER+1 for_loop dbeq b,for_exit <statements> bra for_loop for_exit Basic idea: Count (B) down, and use the ZERO condition as a completion indicator calculation of ITER+1 is done at assembly time make use of “compound” decrement and branch instruction
“Optimized” FOR (0 – 65,535) Key: Use registers as loop counters ITER EQU ___ ; unsigned word (“int”) for_start ldx #ITER+1 for_loop dbeq x,for_exit <statements> bra for_loop for_exit Basic idea: Count (X) down, and use the ZERO condition as a completion indicator calculation of ITER+1 is done at assembly time make use of “compound” decrement and branch instruction Note: In “optimized” FOR constructs, the loop overhead is reduced to 3 instructions
“Optimized” DO (1 – 256) ITER EQU ___ ; unsigned byte (“char”) do_start ldab #ITER do_loop <statements> dbne b,do_loop do_exit code block is executed at least once completion check at bottom of loop
“Optimized” DO (1 – 65,536) ITER EQU ___ ; unsigned word (“int”) do_start ldx #ITER do_loop <statements> dbne x,do_loop do_exit code block is executed at least once completion check at bottom of loop Note: In “optimized” DO constructs, the loop overhead is reduced to 2 instructions