asm Language Programming
The ability to communicate is of great
importance in any field. However, it is only possible if both
communication partners know the same language, i.e follow the same rules
during communication. Using these principles as a starting point, we can
also define communication that occurs between microcontrollers and man .
Language that microcontroller and man use to communicate is called
"assembly language". The title itself has no deeper meaning, and
is analogue to names of other languages , ex. English or French. More
precisely, "assembly language" is just a passing solution.
Programs written in assembly language must be translated into a
"language of zeros and ones" in order for a microcontroller to
understand it. "Assembly language" and "assembler" are
two different notions. The first represents a set of rules used in writing
a program for a microcontroller, and the other is a program on the
personal computer which translates assembly language into a language of
zeros and ones. A program that is translated into "zeros"
and "ones" is also called "machine language".
The process of
communication between a man and a microcontroller
represents a file on the computer disc (or in the memory if it is read in
a microcontroller), and is written according to the rules of assembler or
some other language for microcontroller programming. Man can understand
assembler language as it consists of alphabet signs and words. When writing
a program, certain rules must be followed in order to reach a desired
effect. A Translator interprets each instruction written in
assembly language as a series of zeros and ones which have a meaning for
the internal logic of the microcontroller.
Lets take for instance the instruction "RETURN" that a
microcontroller uses to return from a sub-program.
When the assembler translates it, we get a 14-bit series of zeros and ones
which the microcontroller knows how to interpret.
Example: RETURN 00 0000 0000 1000
Similar to the above instance, each assembler instruction is interpreted as
corresponding to a series of zeros and ones.
The place where this translation of assembly language is found, is called
an "execution" file. We will often meet the name "HEX"
file. This name comes from a hexadecimal representation of that file, as
well as from the suffix "hex" in the title, ex. "test.hex". Once it is generated, the execution file is read in a
microcontroller through a programmer.
An Assembly Language program is written in a program for text
processing (editor) and is capable of producing an ASCII file on the
computer disc or in specialized surroundings such as MPLAB,which will be
explained in the next chapter.
In assembly language MPLAB, numbers can
be represented in decimal, hexadecimal or binary form. We will illustrate
this with a number 240:
Decimal numbers start with a dot,
hexadecimal with 0x, and binary start with b with the number itself under
Assembly language elements
Basic elements of assembly language are:
is a textual designation (generally an easy-to-read word)
for a line in a program, or section of a program where the micro can jump
to - or even the beginning of set of lines of a program. It can also be
used to execute program branching (such as Goto .......) and the program
can even have a condition that must be met for the Goto instruction to be
executed. It is important for a label to start with a letter of the
alphabet or with an underline "_". The length of the label can
be up to 32 characters. It is also important that a label starts in the
Instructions are already defined by the use of a specific microcontroller,
so it only remains for us to follow the instructions for their use in
assembly language. The way we write an instruction is also called
instruction "syntax". In the following example, we can recognize
a mistake in writing because instructions movlp and gotto do not exist for
the PIC16F84 microcontroller.
Operands are the instruction elements for the instruction is being
executed. They are usually registers
is a series of words that a programmer writes to make the
program more clear and legible. It is placed after an instruction, and
must start with a semicolon ";".
is similar to an instruction, but unlike an instruction
it is independent on the microcontroller model, and represents a
characteristic of the assembly language itself. Directives are usually
given purposeful meanings via variables or registers. For example, LEVEL
can be a designation for a variable in RAM memory at address 0Dh. In this
way, the variable at that address can be accessed via LEVEL designation.
This is far easier for a programmer to understand than for him to try to
remember address 0Dh contains information about LEVEL.
a sample program
The following example illustrates a
simple program written in assembly language respecting the basic rules.
When writing a program, beside mandatory rules, there are also some rules
that are not written down but need to be followed. One of them is to write
the name of the program at the beginning, what the program does, its
version, date when it was written, type of microcontroller it was written
for, and the programmer's name.
Since this data isn't important for the
assembly translator, it is written as comments. It should be noted
that a comment always begins with a semicolon and it can be placed in a
new row or it can follow an instruction.
After the opening comment has been written, the directive must be
included. This is shown in the example above.
In order to function properly, we must define several microcontroller
parameters such as: - type of oscillator,
- whether watchdog timer is turned on, and
- whether internal reset circuit is enabled.
All this is defined by the following directive:
When all the needed elements have been defined, we can start writing a
First, it is necessary to determine an address from which the
microcontroller starts, following a power supply start-up. This is (org
The address from which the program starts if an interrupt occurs is (org
Since this is a simple program, it will be enough to direct the
microcontroller to the beginning of a program with a "goto Main"
The instructions found in the Main select memory bank1
(BANK1) in order to access TRISB register, so that port B can be declared
as an output (movlw 0x00, movwf TRISB).
The next step is to select memory bank 0 and place status of logic one on
port B (movlw 0xFF, movwf PORTB), and thus the main program is finished.
We need to make another loop where the micro will be held so it doesn't
"wander" if an error occurs. For that purpose, one infinite loop
is made where the micro is retained while power is connected. The
necessary "end" at the end of each program informs the
assembly translator that no more instructions are in the program.
#DEFINE Exchanges one
part of text for another
#define<text> [<another text>]
Each time <text> appears in the program , it will be exchanged for
<another text >.
#define turned_on 1
#define turned_off 0
INCLUDE Include an additional file in a program
An application of this directive has the effect as though the entire file
was copied to a place where the "include" directive was found.
If the file name is in the square brackets, we are dealing with a system
file, and if it is inside quotation marks, we are dealing with a user
file. The directive "include" contributes to a better layout of
the main program.
CONSTANT Gives a constant numeric value to the textual designation
Each time that <name> appears in program, it will be replaced with
VARIABLE Gives a variable numeric value to textual designation
By using this directive, textual designation changes with particular value.
It differs from CONSTANT directive in that after applying the directive, the value of textual designation can be changed.
SET Defining assembler variable
To the variable <name_variable> is added expression <value>. SET directive is similar to EQU, but with SET directive name of the variable can be redefined following a definition.
level set 0
length set 12
level set 45
EQU Defining assembler constant
<name_constant> equ <value>
To the name of a constant <name_constant> is added value <value>
five equ 5
six equ 6
seven equ 7
ORG Defines an address from which the program is stored in microcontroller memory
This is the most frequently used directive. With the help of this directive we define where some part of a program will be
start in the program memory.
Start org 0×00
The first two instructions following the first 'org' directive are stored from address 00, and the other two from address 10.
End of program
At the end of each program it is necessary to place 'end' directive so that assembly translator would know that there are no more instructions in the program.
IF Conditional program branching
If condition in <conditional_term> was met, part of the program which follows IF directive
would be executed. And if it wasn't, then the part following ELSE or ENDIF directive
would be executed.
ELSE The alternative to
'IF' program block with conditional terms
Used with IF directive as an alternative if conditional term is incorrect.
If time< 50
goto SPEED UP
else goto SLOW DOWN
ENDIF End of conditional program section
Directive is written at the end of a conditional block to inform the assembly translator
that it is the end of the conditional block
WHILE Execution of program section as long as condition is met
Program lines between WHILE and ENDW would be executed as long as condition
was met. If a condition stopped being valid, program would continue executing instructions following ENDW line. Number of instructions between WHILE and ENDW can be 100 at the most, and number of executions 256.
ENDW End of conditional part of the program
Instruction is written at the end of the conditional WHILE block, so that assembly translator would know that it is the end of the conditional block
IFDEF Execution of a part of the program if symbol was defined
If designation <designation> was previously defined (most commonly by #DEFINE instruction), instructions which follow
would be executed until ELSE or ENDIF directives are not would be reached.
ifdef test ;how the test was defined
......; instructions from these lines would execute
#DEFINE, ELSE, ENDIF, IFNDEF, #UNDEFINE
IFNDEF Execution of a part of the program if symbol
If designation <designation> was not previously defined, or if its definition was erased with directive #UNDEFINE, instructions which follow
would be executed until ELSE or ENDIF directives would be reached.
ifndef test ;how the test was undefined
..... .; instructions from these lines would execute
#DEFINE, ELSE, ENDIF, IFDEF, #UNDEFINE
CBLOCK Defining a block for the named constants
Directive is used to give values to named constants. Each following term receives a value greater by one than its precursor. If <increment> parameter is also given, then value given in <increment> parameter is added to the following constant.
Value of <term> parameter is the starting value. If it is not given, it is considered to be zero.
First, second, third ;first=0x02, second=0x03, third=0x04
first : 4, second : 2, third ;first=0x06, second=0x08, third=0x09
ENDC End of constant block definition
Directive was used at the end of a definition of a block of constants so assembly translator could know that there are no more constants.
Defining one byte data
[<label>]db <term> [, <term>,.....,<term>]
Directive reserves a byte in program memory. When there are more terms which need to be assigned a byte each, they will be assigned one after another.
db 't', 0×0f, 'e', 's', 0×12
DE Defining the EEPROM memory byte
[<term>] de <term> [, <term>,....., <term>]
Directive is used for defining EEPROM memory byte. Even though it was first intended only for EEPROM memory, it
could be used for any other location in any memory.
de "Version 1.0" , 0
DT Defining the data table
[<label>] dt <term> [, <term>,........., <term>]
Directive generates RETLW series of instructions, one instruction per each term.
dt "Message", 0
dt first, second, third
_CONFIG Setting the configurational bits
_ _config<term> or_ _config<address>,<term>
Oscillator, watchdog timer application and internal reset circuit are defined. Before using this directive, the processor must be defined using PROCESSOR directive.
PROCESSOR Defining microcontroller model
Instruction sets the type of microcontroller where programming is done.
3.5 Files created as a result of program translation
As a result of the process of translating a program written in assembler language we get files like:
Executing file (Program_Name.HEX)
Program errors file (Program_Name.ERR)
List file (Program_Name.LST)
The first file contains translated program which was read in microcontroller by programming. Its contents can not give any information to programmer, so it will not be considered any further.
The second file contains possible errors that were made in the process of writing, and which were noticed by assembly translator during translation process. Errors can be discovered in a "list" file as well. This file is more suitable though when program is big and viewing the 'list' file takes longer.
The third file is the most useful to programmer. Much information is contained in it, like information about positioning instructions and variables in memory, or error signalization.
Example of 'list' file for the program in this chapter follows. At the top of each page is
stated information about the file name, date when it was translated, and page number. First column contains an address in program memory where a instruction from that row is placed. Second column contains a value of any variable defined by one of the directives : SET, EQU, VARIABLE, CONSTANT or CBLOCK. Third column is reserved for the form of a translated instruction which PIC is executing. The fourth column contains assembler instructions and programmer's comments. Possible errors will appear between rows following a line in which the error occurred.
At the end of the "list" file there is a table of symbols used in a program. Useful element of 'list' file is a graph of memory utilization. At the very end, there is an error statistic as
well as the amount of remaining program memory.