420 likes | 590 Views
Assembler Programming. Chapter 6. EEL-4746 Best Practices. EEL-4746 Best Practices. All programs must begin with the following comment *************************** * EEL-4746 Spring 2004 Semester * Homework #N – Due (Due Date) * Problem #M * Name of Partner A
E N D
Assembler Programming Chapter 6
EEL-4746 Best Practices • All programs must begin with the following comment • *************************** • * EEL-4746 Spring 2004 Semester • * Homework #N – Due (Due Date) • * Problem #M • * Name of Partner A • * Name of Partner B • **************************** • * Description of Program
EEL-4746 Best Practices • All subroutines must begin with the following comment • *************************** • * Subroutine Name: Mysub • * Input parameter list: • * Output parameter list: • * Registers changed list: • **************************** • * Description of Subroutine
EEL-4746 Best Practices • All lines must contain a comment • All labels must end with a semicolon • Must use a symbol for all constants
EEL-4746 Best Practices • Program must have the following format: • Header Comment • *********************** • * Standard Symbols • Data EQU $0000 • Program EQU $E000 • Stack EQU $00FF • Reset EQU $FFFE • ******************* • Place your symbols here • ****************** • * Program • Top: ORG Program • Label: Program line ; comment • ************************** • * Data • ORG Data • Variable {Directive} ; Data goes here • ORG Reset • FDB Top
Additional Comments • To Indent or Not Indent • Not really used in assembly language programming • Upper,Lower, and Mixed Cases • Be consistent • Symbols for constants in ALLUPPERCASE • Labels for in-memory variables in lowercase • Code labels in MixedCase • Instructions all uppercase or all lowercase • Etc • Subroutine Headers • Develop the habit of placing comments before subroutines. The comment should give the function of the subroutine, the input values it expects, and the registers that it modifies.
Pseudo-code • A “fictitious” programming language which allows a general algorithm for a computer program to be developed. • Design process • Develop program using pseudo-code • Convert pseudo-code to 68HC11 assembly language
Structured Assembly Language Programming • If – Then –Else – End IF • Pseudo-Code Syntax • If Variable_A Condition Variable_B Then • Pseudo Code for Then condition • Else (Optional) • Pseudo Code B for Else condition • End If
Structured Assembly Language Programming • LDAA Variable_A • CMPA Variable_B • B?? Else ; Opposite of condition • Code for Then part • …………………………. • BRA END_IF ; need to skip else part • Else : Code for Else part • ……………………….. • END_IF: Rest of Code
Structured Assembly Language Programming • If-Then-Else-End IF • Condition : Branch to Use (Opposite of condition) • <> : BEQ (Branch if equal) • = : BNE (Branch if not equal) • Signed • <= : BGT (Branch if greater than) • < : BGE (Branch if greater than or equal) • >= : BLT (Branch if less than) • > : BLE (Branch if less than or equal) • Unsigned • <= : BHI (Branch if higher) • < : BHS (Branch if higher or same) • >= : BLO (Branch if lower) • > : BLS (Branch if lower or same)
If-Then-Else Example • Pseudo-code • IF temp > max_temp then • Then code • Else • Else code • End If
If-Then-Else Example • Assembly Language • LDAA Temp • CMPA MAX_TEMP • BLS Else • Then code here • BRA ENDIF • ELSE: • ELSE code here • EndIf: • Rest of program here
Structured Assembly Language Programming • Loops • For Loops • While-Do Loop • Do-While or (Repeat – Until) Loops
Structured Assembly Language Programming • For Loops • Pseudo-code Syntax • For loop_index = start_index to end_index • Begin • Code to Execute • …….. • …….. • End For Loop
Structured Assembly Language Programming • Assembly Language • Use one of the registers for the loop index. • A,B=8 bit (255 max) • X,Y=16 bit (65535 max) • Must use memory if index value is greater than 65535 • Example Code Fragment • LDAA #start_index • Loop: Start of Code to Execute (must not change A) • …………. • INCA • CMPA #end_index • BLS Loop
Structured Assembly Language Programming • What if you need the loop index register (e.g. A) in your code? • Example Code Fragment • LDAA #start_index • Loop: Start of Code to Execute • PSHA ; Save A on stack • Use A …………. PULA ; Restore A from stack • INCA • CMPA #end_index • BLS Loop
Structured Assembly Language Programming • For Loops (Count down) • Pseudo-code Syntax • For loop_index = end_index downto start_index • Begin • Code to Execute • …….. • …….. • End For Loop
Structured Assembly Language Programming • Example Code Fragment • LDAA #end_index • Loop: Start of Code to Execute • ………………………. • DECA • CMPA #start_index • BHS Loop
Structured Assembly Language Programming • For Loops (Count down from N to 1) • This counts N items • Pseudo-code Syntax • For loop_index = end_index downto 1 • Begin • Code to Execute • …….. • …….. • End For Loop
Structured Assembly Language Programming • Example Code Fragment • LDAA #N • Loop: Start of Code to Execute • ………………………. • DECA • BNE Loop ; Save one statement
Structured Assembly Language Programming • While-Do Loops • Pseudo-code Syntax • While Variable Condition Constant_VALUE • Do Code Here • Begin • Code to Execute • …….. • …….. • End While
Structured Assembly Language Programming • While-Do Loops • Loop: LDAA Variable • CMPA #Constant_Value • B?? End_While ; (opposite of condition) • Do code here • ……………… • …………….. • BRA Loop • End_While: ; End of While loop
Structured Assembly Language Programming • While-Do • Condition : Branch to Use (Opposite of condition) • <> : BEQ (Branch if equal) • = : BNE (Branch if not equal) • Signed • <= : BGT (Branch if greater than) • < : BGE (Branch if greater than or equal) • >= : BLT (Branch if less than) • > : BLE (Branch if less than or equal) • Unsigned • <= : BHI (Branch if higher) • < : BHS (Branch if higher or same) • >= : BLO (Branch if lower) • > : BLS (Branch if lower or same)
Structured Assembly Language Programming • Example: Temp > #$4F (unsigned) • Pseudo-code: While Temp > $4F Do (Execute your code here) End_While: ; End of While loop
Structured Assembly Language Programming • While Temp > #$4F (unsigned) • Assembly Code Loop: LDAA Temp CMPA #$4F BLS End_While ; (opposite of >) Do code here ……………… …………….. BRA Loop End_While: ; End of While loop
Structured Assembly Language Programming • Do-While or (Repeat-Until) Loops • Pseudo-code Syntax • Do (or Repeat) • Begin • Code to Execute • …….. • …….. • While Condition (or Until Condition)
Structured Assembly Language Programming • Do-While or (Repeat-Until) Loops • Assembly Language Syntax • Loop: • Do Code Here • …….. • …….. • LDAA Variable • CMPA #Constant • B?? Loop ; (same as condition)
Structured Assembly Language Programming • Do-While or (Repeat – Until) • Condition : Branch to Use (Same as condition) • = : BEQ (Branch if equal) • <> : BNE (Branch if not equal) • Signed • > : BGT (Branch if greater than) • >= : BGE (Branch if greater than or equal) • < : BLT (Branch if less than) • <= : BLE (Branch if less than or equal) • Unsigned • > : BHI (Branch if higher) • >= : BHS (Branch if higher or same) • < : BLO (Branch if lower) • <= : BLS (Branch if lower or same)
Example • Write a 68HC11 assembly language program that converts X into an equivalent ASCII signed decimal value. Store your result in a memory location labeled: Result.
Pseudo-code X = Number_to_convert sign = “+” if X < 0 then sign = “-” X = -X end If result[0] = sign call X2ASC(X) end program • X2ASC is a subroutine that converts the X register (unsigned) to ASCII We’ll put this code intoa subroutine calledSX2ASC that convertsthe X register (signed)to ASCII.
Let’s convert the code… • For this line of pseudo-code: X = Number_to_convert • We’ll create the following code… NUMBER: EQU $8001 ; -32767 … ORG CODE_AREA Main: LDX #NUMBER ;Put it in regX JSR SX2ASC ;Signed convert End: BRA End ;Infinite loop
Next line • At the start of the SX2ASC subroutine, we have the pseudocode line: sign = “+” • We’ll convert this to: ORG DATA_AREA … sign: RMB 1 ;1 byte for sign char … ORG CODE_AREA … SX2ASC: LDAA #’+ ; Take an ASCII + sign. STAA sign ; Store it in “sign” var.
Next line • Next, we have: if X < 0 then … end if • This converts to the assembly: CPX #0 ; Compare X to 0. BHS endIf ; If X>=0, skip if body … (IF body goes here) endIf: … (code after IF goes here)
A more difficult case • Consider the pseudocode line: X = −X (X gets negative X) • Problem: There’s no NEGX instruction! • How can we work around this? • One solution: varX RMB 2 ; Reserve space for X in mem. … STX varX ; Save X in memory at varX LDD #0 ; Load accum. D with a 0 SUBD varX ; Let D = 0 – varX = -X XGDX ; Copy D back to X.
Full SX2ASC in assembly SX2ASC: LDAA #'+ ; Take an ASCII "+" sign. STAA sign ; Store it in "sign" variable. CPX #0 ; Compare X to 0. BHS endIf ; If X < 0, then... LDAA #'- ; Take an ASCII "-" sign. STAA sign ; Store it in "sign" variable. STX varX ; Save X in "varX" variable. LDD #0 ; D = 0. SUBD varX ; D = 0 - varX = -varX = -X. XGDX ; Copy D back to X. endIf: LDAA sign ; A = sign character. STAA result+0 ; Store sign char. in result[0]. JSR X2ASC ; Conv. unsigned X to result[1-5]. RTS ; End of subroutine; return. X = −X
Pseudo-code: X2ASC (w. divide) function X2ASC(X,result) D = X for B = 0 to 3 A = floor(D / convert[B]) ; where convert[]= 10000,1000,100,10 D = D – A*convert[B] ; Let D be the remainder A = A or #$30 ; Convert A from 0-9 to ASCII result[B+1] = A end for A = D ; D should have the ones A = A or #$30 ; Convert to ASCII result[4] = A end function Note: When converting this to working assemblycode, we must be careful about overlapping registers.
for loop outline • The skeleton of our for loop: • for B = 0 to 3 … (body of for loop)end for • Translates to: LDAB #0 forBody: … ;body code goes here INCB ; B = B + 1 CMPB #3 ; Compare B to 3 BLS forBody ; If B<=3, continue • But, we must be careful to preserve the value of B within the body code!
Accessing an array of words • We can set up the convert[] array as follows: convert FDB 10000,1000,100,10 • But, how do we access convert[B]? CLRA ; Effectively sets D=B ASLD ; Double D, it’s 2B. XGDY ; Transfer this to Y LDX convert,Y ; X = *(convert+2B) • But, this only works if convert array is on page 0! • More generally, we’d have to do this after the ASLD: ADDD #convert ; D = convert+2B XGDY ; Transfer D to Y LDX 0,Y ; X = *Y = convert[B]
Unsigned X2ASC in assembly X2ASC: STX varD ; Initialize variable D = X. LDAB #0 ; For B = 0 to 3, ForBody:STAB varB ; Save variable B. CLRA ; Clear MSB of accumulator D. ASLD ; Double D to get 2*varB. XGDY ; Move it into Y. LDX convert,Y ; Let X = *(convert+Y) = convert[varB] LDD varD ; Load old variable D. IDIV ; (X,D) = (quotient,remainder) of D/X. STX quot ; Save quotient temporarily. STD varD ; Save remainder as new variable D. CLRA ; Clear MSB of accumulator D. LDAB varB ; Set LSB of D = variable B. XGDY ; Move value of B from D into Y. INY ; Increment Y to be varB+1. LDAA quot+1 ; A = LSB of quotient. ORAA #$30 ; Convert A to ASCII. STAA result,Y ; result[varB+1] = A. LDAB varB ; Load old value of variable B. INCB ; Increment B to next value. CMPB #3 ; Compare B with 3. BLS ForBody ; End For. (Continue while B <= 3.) LDAA varD+1 ; A = LSB of D (final remainder). ORAA #$30 ; Convert A to ASCII. STAA result+5 ; result[5] = A. RTS ; Subroutine done; return. X=convert[B] result[B+1]=A+$30
Pseudo-code: X2ASC (w/o divide) This version avoids doing divisionand would work on a processorwithout a divide instruction. Function X2ASC(X,Result) D = X For B = 0 to 3 A = 0 ; Count the number of times Convert can be subtracted from D While D>0 Do A = A + 1 D = D – Convert[B] ; Convert= 10000,1000,100,10 End While D = D + Convert[B] A = A – 1 A = A OR #$30 ; Convert A from 0-9 to ASCII Result[B] = A END For A = D ; D should have the ones A = A OR #$30 ; Convert to ASCII Result[4] = A End Function Note: When converting this to HC11 assemblycode, we must be careful because the HC11’sregister D overlaps registers A and B.