You are on page 1of 10

7/15/10

ECE 4436 ASSEMBLY LANGUAGE CODING STANDARD FOR MC9S12


1.0 INTRODUCTION
Standards eliminate variability and provide consistency among programs. Much of the difficulty in
establishing standards stems from the notion that they should be optimal. However, to be successfully
applied, standards must simply represent an agreement on certain aspects of the programming process.
Described here is the ECE 4436 coding and documentation standard for assembly language programming
on the MC9S12-series microprocessor.
2.0 LINE FORMAT
All source lines shall consist of from one to a maximum of eighty characters. Assembly language code
lines shall have the following format:
Label/Name field - If present, the label or variable name shall start in column 1. A label for an
instruction that is a branch target shall be on a line by itself preceding the target instruction.
Operation field - the operation field shall start at tab stop 1 (column 9). Following a variable name
longer than 7 characters, simply leave a space and then start the operation field.
Operand field - the operand field shall start at tab stop 2 (column 17).
Comments field - the comments field shall start at tab stop 4 (column 33). However, if the operand
field extends this far, simply leave a space and then start the comment. Comment text begins
with a semicolon.
Whole line comments shall begin with a semicolon and be bracketed by lines containing only a
leading semicolon. The text of the comment begins in column 3; text on subsequent lines is
indented. Occasionally a single line comment without the bracketing lines is appropriate.
The tab stop columns above are only suggested, and they correspond to the defaults in many editors. You
can change them as long as you are consistent and your resulting code "looks good" and is readable. You
might, for example, move the operation field to the right, or start the operand and comment fields sooner
since the op codes don't require much space. Just be sure that all fields of one type line up in each code
block.
For example,
;
; This illustrates a whole line comment.
;
This is a second line that is indented.
;
count: DC.B
60
;starting count
start:
ldab
count
;initialize counter
Entire program blocks, for example, the interrupt vectors, can be more prominently set off:
;**************************************************************
;
Main Bang-Bang Control Loop
;**************************************************************
What is most important is to show hierarchy that improves readability, in a fashion similar to a book or
long report that has chapters, sections, subsections, etc.

7/15/10

3.0 COMMENTS
3.1 Content
Comment all coding to convey the global role of an instruction, and not simply a literal translation of the
instruction into English. In general, this will consist of a comment per line of code, except when the
meaning is obvious without the comment. If a particularly difficult, obscure, or elegant instruction
sequence is used, a paragraph of comments should immediately precede that section of code.
3.2 Decision Points
Comments at decision points should indicate clearly what decision is being made and what the outcomes
are. For example:
cmpa
max
;is it maximum?
beq
exit
;if yes, time to exit
; else,...
3.3 Subroutine Calls
Comments at the point of call to a subroutine should state clearly why the subroutine is being called.
3.4 Data
It is perhaps even more important to comment data than instructions. Describe the function for which the
data is used. Tables should be thoroughly commented.
4.0 NAMING STANDARDS
4.1 Registers
CPU Registers - Only the standard names are permitted as register names; do not equate a register to
another name even if the assembler allows it.
Device Registers - These are symbolically named identically to the hardware notation used in the device
documentation. For example, if the port A data register is documented as PORTA, only this symbolic
name may be used to refer to this register.
4.2 Instruction Mnemonics
Executable instruction mnemonics should be written in all lower case, e.g., ldaa.
4.3 Assembler Directives
Assembler directives should be written in all upper case, e.g., ORG.
4.4 Equated Symbols
Equated symbols should be all (or mostly) upper case. The name should express the meaning of what the
symbol is defining, e.g., RWDATA for the read/write data area. Symbols should be arranged alphabetically
within functional groups unless there is another obvious useful order.
Program-Local Symbols - Self-relative address arithmetic (*+n) is absolutely forbidden in branch
instructions (except the special case: bra *); its use in other contexts must be rare.
Other Symbols - Frequently-used bit patterns such as CR and LF can be made conventional symbols on
an as-needed basis. In general, hard-coded constant values should be avoided; use symbols instead. For
example, in referring to the length of a buffer, the best method is to refer to a symbol whose value is
automatically the correct length of the buffer.

7/15/10

;
; User Equates
;
LARRAY: EQU
100
;
; Local Data Read/Write
;
array: DC.B
LARRAY

;length of array

;work array

This method has several advantages. First, if a single constant that is referred to in numerous places in
the code must be altered, you need perform only one edit (to the symbol definition) to effect the change.
Second, if all the symbols are gathered in one place in alphabetical order, reading the code is much
simplified. Third, you can find all references to a symbol in a cross-reference listing. The cross-reference
capability allows you to examine all the references to a symbol and confidently assess the effects of
altering the symbol definition. Fourth, using a symbol name reflecting the true meaning behind a value
makes the code clearer than using the number itself. These advantages are lost if you use constants.
4.5 Data Labels
Labels of read-only and read/write data should be all lower case. The name should express the meaning
of the data the symbol is defining, e.g., counter.
4.6 Subroutine Names
The name of a subroutine should be all lower case and should be on a line by itself preceding the target
instruction. The name should convey the function of the subroutine, e.g., print_header.
4.7 Branch Targets
The label of a branch or call target should be all lower case and should be on a line by itself preceding the
target instruction. In a short program the name can express the meaning of the target block of
instructions. However, in larger programs it is best to use an alphabetically ordered sequence of labels
related to the name of the program module. For example, in the subroutine named print_header, the
branch targets could be: ph10, ph20, ph30, etc.
4.8 Multiword Names
Multiword names can use an underscore _ to separate the words, e.g., print_header. Alternatively,
uppercase can be used for the second and succeeding words, e.g., printHeader.
4.9 Table Entry Offsets
Equated symbols that represent offsets to individual entries in a table or structure should be of the form
table.ITEM. For example, if the a parameter table parms holds two parameters to be passed to a
subroutine, the name of an array and the length of the array, the equated symbol offsets to those items
could be parms.ADDR and parms.LEN, whose values would be 0 and 2, respectively.
4.10 Constant Data
Constants should be expressed in the base and format that conveys the true meaning and context. Let the
assembler do the work of converting to machine format. For example:
year: DC.B 365
ldaa #'N'
ORG $0800

;days in year

NOT
NOT
NOT

year: DC.B $16D


ldaa #$4E
ORG 2048

7/15/10

5.0 MODULAR PROGRAMMING


5.1 General Comments on Modules
No other characteristic has more impact on the ultimate engineering success of a system than does
modularity. A module provides a single distinct function. The main program module implements the
major functions of the flow chart by calling a number of subroutine modules.
All code is read-only. Code and data areas are distinct and each contains explanatory text.
5.2 The Main Program Preface
Program modules adhere to a strict format. This format adds to the readability, understandability, and
maintainability of the program. The following sections are included in each program.
1. Main Program Heading. Give the authors names, program name, and the date (assignment due date).
2. Program Function - Detailed. This section of the source file can be as general or specific as needed to
describe the functions of the program. A complex program should have lengthy discussion; a simple
program need not have as much. This description should include instructions on how the user interacts
with the program.
3. Equated Symbols. A list of the definitions of all equated local symbols used in the program. These
definitions appear one per line and in alphabetical order within functional groups fully commented.
These equates must be placed before the code that uses them; but they must also be placed after any
symbols to which they refer. Therefore, it may be necessary to have two sections of equates, one before
the data block and one after the data block.
Standard system equates such as I/O port symbols should be defined separately from local user equates.
4. RAM storage: Local Variables. This section defines such data as buffers, tables, and status words.
5. ROM storage: Constants and program code. This consists of the read-only data constants, followed by
the program code itself.
In general,
a. Items 1-2 above appear on the same page and will not have explicit headings.
b. Items 3-5 will have headings that start in column 3, preceded and followed by blank comment lines.
Items that do not apply may be omitted.

7/15/10

A sample template for the main program preface follows.


; Lab x - ECE 4436 - Fall 2010
; Your Names
;
This program ...
;
;******************************************
; External symbol declarations (imported)
XREF
__SEG_END_SSTACK
;******************************************
; Internal symbol definitions (exported)
XDEF
Entry, main
;******************************************
; Include derivative specific macros
INCLUDE 'mc9s12c32.inc'
;******************************************
; Constant equates
User Program Equates
;******************************************
; Code Section Start
Code:
SECTION
Entry:
main:
; Initialize stack pointer
lds
#__SEG_END_SSTACK
; Initialize ...
Begin main program code
bra

or continuous loop

;******************************************
; Constant data in ROM
Const: SECTION
Constant definitions
;******************************************
; Variable data in RAM
Data:
SECTION
Variable Data

7/15/10

A sample of a documented program is given below:


TITLE "Lab 1 - ECE 4436"
;******************************************
; Lab 1 - ECE 4436 - Spring 2008
; Clark Kent and Lois Lane
;
This program fills a table with consecutive integers,
;
starting with the value in the variable first.
;
;******************************************
; External symbol declarations
XREF
__SEG_END_SSTACK
;******************************************
; Internal symbol definitions
XDEF
Entry, main
;******************************************
; Include derivative specific macros
INCLUDE 'mc9s12c32.inc'
;******************************************
; Constant equates
TABLEN: EQ
10
;length of table
;******************************************
; Code Section Start
Code:
SECTION
Entry:
main:
; Initialize stack pointer
lds
#__SEG_END_SSTACK
; Initialize loop data
ldaa
first
;init integer counter
ldab
#TABLEN
;init counter to # entries
ldx
#table
;init pointer to table start
;
; Loop, filling the table with integers
;
addloop:
inca
;increment to next integer
staa
0,x
;store in table
inx
;point to next slot in table
decb
;decrement counter, done?
bne
addloop
; if not, repeat
; All done
bra
*
;spin here
;******************************************
; Constant data in ROM
Const: SECTION
first: DC.B
5
;first integer value
;******************************************
; Variable data in RAM
Data:
SECTION
table: DS.B
TABLEN
;to be filled in with integers

7/15/10

5.3 Subroutines
As stated above, modular programming is accomplished by implementing major functions of the flow
chart in separate subroutine modules. Of primary importance is that the interface to the calling module be
clear and understandable. This clarity requires adherence to a set of calling and return conventions and
careful documentation of the interface in the subroutine.
5.3.1 Calling Conventions - The following calling conventions must be observed.
Argument Passing The standard methods for passing arguments to and from a subroutine used in this
course are: all arguments in the registers, all arguments on the stack, or a combination of these two.
Register Conventions - A common convention is that on entry a subroutine saves all registers it intends to
alter except result registers, and then restores them on exit (state preservation). The only exception to this
is a short convenience subroutine that is not designed to be reused in other programs. Saving and
restoring occurs on the stack.
5.3.2 Exiting - All subroutine exits occur through a single rts instruction.
5.3.3 Argument Checking - Subroutines are responsible for verifying the validity of arguments passed to
them. The design of a subroutine's calling sequence should aim at minimizing the validity checks by
minimizing invalid combinations.
5.3.4 Local Data If at all possible, the subroutine should store all local variables on the stack, rather
than using dedicated space in RAM. Use local symbol offsets to access the variables in the stack frame.
Local constants should be stored immediately preceding the subroutine code.
5.3.5 Subroutine Format
The following documentation sections must be included in comments within each subroutine.
1. Subroutine Name. Name (entry point) used to call the subroutine.
2. Subroutine Function. This section can be as general or specific as necessary to clearly describe the
function of the subroutine. At a minimum, it should include which registers are destroyed.
3. Inputs. A list of the inputs expected by the subroutine. This includes the calling sequence, condition
flag settings, and global data settings.
4. Outputs. A list of the outputs produced as a result of entering this subroutine. These include delivered
results, condition flag settings, but not side effects (all these outputs are visible to the caller).
5. Effects. A list of all effects, including side effects, produced as a result of entering this subroutine.
Effects include alterations in the state of the system not explicitly expected in the calling sequence, or
those not visible to the caller.
5.3.5 Naming in Subroutines
All symbols defined in the subroutine should be prefixed with the name of the subroutine (or a shortened
version thereof) in order to avoid naming conflicts. After the prefix, follow the standard rules for naming.
For example, in the subroutine named clear:
1. Branch target: clear1, clear2, clear_loop.
2. Local constant data: clear_max.
3. Local symbol equate: clear_LO4.
4. Local offset equate: clear.ADDR

7/15/10

A sample template for the subroutine preface follows.


;
; SUBROUTINE: name
;
; Subroutine function-details
;
; INPUTS:
;
;
Description of inputs
;
; OUTPUTS:
;
;
Description of outputs
;
; EFFECTS:
;
;
Description of effects
;
Begin Subroutine Code
An example of a documented subroutine is given below:
;
; SUBROUTINE: clear
;
; This routine clears an array to all zeroes.
;
Registers A, B, X are destroyed.
;
; INPUTS:
;
;
The calling sequence is:
;
;
< (X) = address of array >
;
< (B) = length of array in words >
;
jsr clear
;
; OUTPUTS:
;
;
The array is cleared to all zeroes.
;
clear:
tstb
beq
clear2
;exit if zero-length
clra
;obtain a zero
clear1:
staa
0,x+
;store zero into array
dbne
b,clear1
;loop if not done
clear2:
rts
;else return

7/15/10

6.0 FORMATTING STANDARDS


6.1 Flow of Execution
Programs will be organized on the listing such that they flow down the page without inefficient,
unnecessary branching. For example:
|
|
/ \
/
\
not equal /
\ equal
+-----------------/ TEST \----------------+
|
\
/
|
|
\
/
|
|
\
/
+------+------+
|
\ /
|
stuff
|
|
|
+------+------+
|
+------------+
|
+------------->|
EXIT
|<-------------+
+------------+
will appear on the listing as:
cmpa
bne
exit
.
(do stuff)
.
exit:
rather than:
cmpa
beq
stuff
bra
exit
stuff:
.
(do stuff)
.
exit:
Generally, anytime you have a conditional branch followed by an unconditional branch, the pair can
usually be replaced by a single conditional branch of the complementary sense, as in the example above.

7/15/10

6.2 Common Exits


A common exit, for example, a return from a subroutine, appears as the last code sequence on the listing.
Thus the flow chart:
+---------+
+---------+
+----------+
+---------+
|
1
|
|
2
|
|
3
|
|
4
|
+---------+
+---------+
+----------+
+---------+
|
|
|
|
|
|
|
|
|
|
|
|
|
| +---------+
|
+--------------+->|
EXIT |<-+---------------+
+---------+
will appear on the listing as:
pr1:
.
bra
exit
pr2:
.
bra
exit
pr3:
.
bra
exit
pr4:
.
exit:
rts
and not as:
pr1:
exit:
pr2:
pr3:
pr4:

.
rts
.
bra

exit

.
bra

exit

.
bra

exit

You might also like