Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 56

3.

Embedded Programs
3.1 Introduction
3.1.1 High-Level Code
3.1.2 Machine Language
3.1.3 Assembly Language Code
3.2 Program translation process
3.3 Representation of programs and their execution flow
3.4 Fundamentals of assembly language and linking
3.4.1 Directives
3.4.2 Labels in Instructions
3.4.3 Source Executable Code
3.5 Mapping tasks in compilation

1
3.1 INTRODUCTION
 Programming provides us with the flexibility to use the same
hardware core for different applications.
 A device whose performance can be modified through some
sort of instructions is called a programmable or configurable
device
 Most I/O ports and peripherals are examples of these blocks;
their configuration should be part of our program design
 Assembly programming for the MSP430 microcontrollers is
introduced in this chapter
 The two most popular assemblers for the MSP430 are the
IAR assembler by Softbaugh and Code Composer Studio
(CCS) from Texas Instruments
2
3.1 INTRODUCTION
 Programs are written using a programming language with
specific rules of syntax. These languages are found in three
main levels:
 Machine language,
 Assembly language, and
 High level language

 To illustrate the differences among them, let us consider the


code of an LED in the three levels

3
3.1 INTRODUCTION
oThe program toggles on and off an LED connected to pin 0
of port 1 (P1.0) of the microcontroller, as illustrated in Figure
3.1. Toggling is achieved by changing the voltage level at the
pin

Figure 3.1 Simplified hardware connection diagram for LED in board

4
3.1 INTRODUCTION
 The algorithm to achieve this goal is described by the
flowcharts of Figure 3.2, where (a) illustrates the process
in its general terms, and (b) expands the different steps in
more detailed actions.

Figure 3.2 Flow diagram for the blinking LED: a) General Concept; b) Expanded flow diagram 5
3.1.1 HIGH-LEVEL CODE

 Figure 3.3 shows a code in C language which executes the


desired task.
 Readers with some proficiency in C will understand this
source code without problem and associate it with the flow
graph. The compiler takes care of the “set up stack” step.

Figure 3.3 C language code for LED toggling


3.1.1 HIGH-LEVEL CODE
 Despite this, high-level programming is more independent of
the hardware structure, closer to our way of thinking, and
easier to grasp.
 These are some of many reasons why this level is preferred
for most applications.
 A drawback is that this language is not understood by the
machine. We need tools, called compilers and interpreters, to
make the appropriate translation
 The final machine product depends on the compiler used.

 Engineers also developed software tools called debuggers to


help correct programming errors, usually called bugs;
correcting them is called debugging.
7
3.1.2 MACHINE LANGUAGE
 Since digital systems only “understand” zeros (0) and ones
(1), this is how the executable code, i.e., the set of instructions
executed by the CPU, is presented to the system
 A program written in zeros and ones is a binary machine
language program. The example in Listing 3.2 of Figure 3.4
is for the flow graph of Figure 3.2
 The hex notation version in Listing 3.3, called hex machine
language, is the form in which debuggers present machine
language to users and also the syntax with which embedded
programmers deal with this level

8
3.1.2 MACHINE LANGUAGE
 Here, each line represents an instruction machine language is
not user friendly and hence the need of other programming
levels
 Instructions for the MSP430 CPU consist of one, two or three
16-bit words.
 The leading one is the instruction word, with information
relative to the instruction and operands.

9
Figure 3.4 Executable machine language code for the example of Figure 3.1
3.1.3 ASSEMBLY LANGUAGE CODE
 The first step toward a friendlier syntax was the assembly language,
compiled with assemblers
 instruction is now a machine instruction encoded in amore “human like”
form.
 Translating a machine instruction into its assembly form is to disassembly
and the software tool for this task is a disassembler.
 Figure 3.5 shows the assembly and hex versions of the executable code

10
Figure 3.5 Assembly version for Figure 3.4-Hex machine version shown for comparison
3.2 PROGRAM TRANSLATION PROCESS
 High level languages arose to allow people to program
without having to know all the hardware details of the
computer
 An important feature is that an instruction in a high level
language would typically correspond to several instructions
in machine code
 mapping of each of the high level language instructions into
machine code and their corresponding use of the functional
units
 the programmer has in effect lost the ability to use the
hardware in the most efficient way
 For most programmers, human-friendly characteristics of
high level language for computer programming make it a
“natural choice” for embedded programming as well 11
3.2 PROGRAM TRANSLATION PROCESS
 C language has features that make it attractive for this sort of
applications
 Perhaps the most important one is that it allows the programmer
to manipulate memory locations with very little overhead added
 Since input/output units can be treated as memory, C will also
allow the programmer to control them directly
 In general, you use C language for embedded systems when one
or more of the following reasons apply:
 tight control of each and every resource of the architecture is not
necessary;
 efficiency in the use of resources such as memory and power are not a
concern;
 ease of software reuse;
 company policy or user requirements;
 lack of knowledge of assembly language and of the particular 12

architecture.
3.2 PROGRAM TRANSLATION PROCESS

 On the other hand, you use assembly language for embedded


systems when one or more of the following reasons apply:
 itis imperative or highly desirable that resources be efficiently
handled;
 there is an appropriate knowledge of the assembly language and of
the particular architecture;
 company policy or user requirements.
o In embedded systems, sometimes it becomes imperative to
work both aspects.
o Hence, unlike what we could design as “typical” C
programming, where the complete source is written in the
same language, compilers for embedded systems provide
methods to mix both languages.
13
3.2 PROGRAM TRANSLATION PROCESS
 A compiler is a program developed to translate a high-level
language source code into the machine code of the system of
interest
 For a variety of reasons, compilers are designed in different
ways
 Some produce machine code other than for the machine in
which they are running
 Others translate from one high level language into another
high level language or from a high level language into
assembly language
 The term cross-compiler is used to define these type of
translators
 When the embedded CPU itself cannot host a compiler, or a
compiler is simply not available to run on a particular CPU, a 14

cross-compiler is used and run on other machine


3.2 PROGRAM TRANSLATION PROCESS
 There are also optimizing compilers, i.e., compilers (or cross-
compilers) in which code optimizing techniques are in place
 These are compilers designed to help the code execute faster,
and include techniques such as constant propagation, inter-
procedural analysis, variable or register reduction, inline
expansion, unreachable code elimination, loop permutation,
etc.
 In terms of software development, an Integrated
Development System or IDE is an application that usually
consists of an editor, a compiler, a linker, and a debugger, all
within the same package.
 The IDE may also include other programs such as a
graphical user interface or GUI, a spell checker, an auto-
15
completion tool, a simulator, and many other features.
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW
 In this section we are going to discuss some general rules of
C programming and introduce certain specifics of C
programming for 8051 series of microcontrollers.
i. Introduction to C Programming for Embedded Systems
 Most common programming languages for embedded systems are
C, BASIC and assembly languages
 C used for embedded systems is slightly different compared to C
used for general purpose (under a PC platform)
 Programs for embedded systems are usually expected to monitor
and control external devices and directly manipulate and use the
internal architecture of the processor such as interrupt handling,
timers, serial communications and other available features

16
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW
i. Introduction to C Programming for Embedded Systems
 There are many factors to consider when selecting languages for
embedded systems
 Efficiency - Programs must be as short as possible and memory must be
used efficiently.
 Speed - Programs must run as fast as possible.
 Ease of implementation
 Maintainability
 Readability
 C compilers for embedded systems must provide ways to examine
and utilize various features of the microcontroller's internal and
external architecture; this includes:
 Interrupt Service Routines
 Reading from and writing to internal and external memories
 Bit manipulation 17
 Implementation of timers / counters
 Examination of internal registers
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW
i. Introduction to C Programming for Embedded Systems
 Standard C compiler communicates with the hardware
components via the operating system of the machine but the
C compiler for the embedded system must communicate
directly with the processor and its components
 For example consider this statement:
 Printf (" C - Programming for 8051\n");
 In standard C running on a PC platform, the statement causes
the string inside the quotation to be displayed on the screen.
 The same statement in an embedded system causes the string
to be transmitted via the serial port pin (i.e TXD) of the
microcontroller provided the serial port has been initialized
and enabled. 18
3.3 REPRESENTATION OF PROGRAMS AND
THEIR EXECUTION FLOW
 - Another example:
 c=getch();

 In standard C running on a PC platform this causes a


character to be read from the keyboard on a PC.
 In an embedded system the instruction causes a character to
be read from the serial pin (i.e. RXD) of the microcontroller.
ii.Template for Embedded C Program
 #include <reg66x.h>
void main(void)
{
// body of the program goes here
}
19
3.3 REPRESENTATION OF PROGRAMS AND
THEIR EXECUTION FLOW
 the first line of the template is the C directive “#include
<reg66x.h>”
 this tells the compiler that during compilation, it should look
into this file for symbols not defined within the program
 “reg66x.h” file simple defines the internal special function
registers and their addresses
 Note that in C numbers that are hexadecimal are represented
by the 0x.
 the next line in the template declares the beginning of the body of
the main part of the program
 the main part of the program is treated as any other function in C
program
 every C program should have a main function 20
3.3 REPRESENTATION OF PROGRAMS AND
THEIR EXECUTION FLOW
 functions are like “procedures” and “subroutines” in other languages
 C function may be written in one of the following formats:
 it may require some parameters to work on
 it may return a value that it evaluates or determines
 it may neither require parameters nor return any value
 if a function requires any parameters, they are placed inside the brackets
following the name of the function
 if a function should return a value, it is declared just before the name of the
function
 when the word ‘void’ is used before the function name it indicates that the
function does not return any value
 when the word ‘void’ is used between the brackets it indicates that the function
does not require any parameters
 main function declaration:
 void main(void)
21
 therefore, indicates that the main function requires no parameters and that it
does not return any value.
3.3 REPRESENTATION OF PROGRAMS AND
THEIR EXECUTION FLOW
iii. C Directives
 #include is one of many C directives. It is used to insert the
contents of another file into the source code of the current file
 There are two slightly different form of using #include
directive:
#include < filename > or #include “filename”
 The first form (with the angle brackets) will search for the
include file in certain locations known to the compiler and it
is used to include standard system header files (such are
stdlib.h and stdio.h in standard C).
 The second form (with the double quotes) will search for the
file in the same directory as the source file and this is used for
header files specific to the program and usually written by the 22
programmer
3.3 REPRESENTATION OF PROGRAMS AND
THEIR EXECUTION FLOW
 All directives are preceded with a “#” symbol another useful
directive is a #define directive
 #define directive associates a symbolic name with some
numerical value or text
 The value of “ON” in the program can be defined as 0xFF
throughout the program using:
#define ON 0xFF
 This approach may be used to define various numerical values in
the program using more readable and understandable symbols
 The advantage of using symbols rather than the actual numerical
values is that, if you need to change the value, all you need to do
is to change the number that is assigned to the symbol in the
define statement rather than changing it within the program which 23
in some cases may be a large program and therefore tedious to do
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW
 Example 1: Program to turn the LEDs on port 1 ON (see
Figure 3.6).
#include <reg66x.h>
void main(void)
{
P1 = 0xFF;
}

Figure 3.6 LEDs and Switches Interfaced to Port 1 and Port 0 of 8051 Microcontroller

 The body of the main function consists of just one statement


and that is P1=0xFF. This tells the compiler to send the
number 0xFF which is the hexadecimal equivalent of 255 or
in binary (11111111) to port 1 which in turn causes the 8
24
LEDs in port 1 to turn ON.
3.3 REPRESENTATION OF PROGRAMS AND
THEIR EXECUTION FLOW
 Note that just like the line in the main body of the program, every
line of a C program must end with a semicolon (i.e. ;) except in some
special occasions.
 Alternative version of this program using directive #define.
#include <reg66x.h>
#define ON 0xFF
void main(void)
{
P1 = ON;
}
 In the above example the value of “ON” is defined as 0xFF using:
#define ON 0xFF
 and the statement in the body of the program is then written as: 25
P1 = ON;
3.3 REPRESENTATION OF PROGRAMS AND
THEIR EXECUTION FLOW
iv. Programming Time Delays
 For various reasons it might be necessary to include some sort
of time delay routine in most of the embedded system programs
 Sophisticated and very accurate techniques using
timers/counters in the processor exist to achieve this one simple
approach (not involving timers) is to let the processor count for
a while before it continues
for(j=0; j<=255; j=j+1)
{
;
}
 Once the loop counter reaches the value of 255 the program
will exit the loop and continue execution with the first 26
statement following the loop section
3.3 REPRESENTATION OF PROGRAMS AND
THEIR EXECUTION FLOW
 For a longer delays we can use a nested loop structure, i.e.
loop within the loop:
for(i=0; i<=255; i=i+1)
{
for(j=0; j<=255; j=j+1)
{
;
}
}
 Note that with this structure the program counts to 255 x 255
v. Indefinite Loops
 Embedded system might be required to continuously execute
a section of a program indefinitely
27
3.3 REPRESENTATION OF PROGRAMS AND
THEIR EXECUTION FLOW
 To achieve this indefinite loop (loop without any exit
condition) can be used. The statement that performs this is:
for(;;)
{
}
 Part of the program to be repeated indefinitely must then be
placed in between the curly brackets after the for(; ;)
statement.
vi. Variables in Embedded C
 Variables in C program are expected to change within a
program
 Variables in C may consist of a single letter or a combination
28
of a number of letters and numbers
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW
 Spaces and punctuation are not allowed as part of a variable
name
 C is a case sensitive language (therefore I and i are treated as
two separate variables)
 In a C program variables must be declared immediately after
the curly bracket marking the beginning of a function to
declare a variable, its type must be defined, it provides
information to the compiler of its storage requirement
 Some of the more common types supported by C are listed in
the table below

29
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW
Type Size Range
unsigned char 1 byte 0 to 255
(signed) char 1 byte -128 to 127
unsigned int 2 bytes 0 to 65535
(signed) int 2 bytes -32768 to 32767
bit 1 bit 0 or 1 (RAM bit-addressable part of memory only)
sbit 1bit 0 or 1 (SFR bit-addressable part of memory only)
sfr 8bit RAM addresses 80h-FFh only

•Definition of type of a variable in a C program is an important factor in the


efficiency of a program
•Depending on the type of a variable the compiler reserves memory spaces for that
variable
•Consider the following guidelines when selecting the type of variables
 if speed is important and sign is not important, make every variable unsigned
 unsigned char is the most common type to use in programming 8051
microcontroller as most registers in the processors are of size 8-bits (i.e one 30
byte)
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW

Example 2: Program to indefinitely flash all LEDs on port
1 at a rate of 1 second
#include <reg66x.h>
void main(void)
{
unsigned char i,j;
for(;;)
{
P1 = 0xFF; /* Turn All LEDs ON */
for(i=0; i<=255; i=i+1)
{
for(j=0; j<=255; j=j+1)
{
;
}
}
P1 = 0x00; /* Turn All LEDs OFF */
for(i=0; i<=255; i=i+1)
{
for(j=0; j<=255; j=j+1)
{
;
}
}
31
}
}
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW
vii. C Functions
 When a part of a program must be repeated more than once, a
more efficient way of implementing is to call the block to be
repeated a name and simple use the name when the block is
needed
 This leads to implementation of C function in the program

 The function (block) must be declared before the main program


and defined, normally immediately after the main program is
ended
 Rules for function declaration are same as for declaration of main
function
void DELAY (void)
 The above function declaration informs the compiler that there
32
will be a function called DELAY, requiring no parameters and
returning no parameters
3.3 REPRESENTATION OF PROGRAMS AND
THEIR EXECUTION FLOW
 The name of a function must follow the rules for the name of
a variable - the function name may not have spaces, or any
punctuation
 A use of functions is advisable as functions make programs
shorter and readable, a shorter program also requires less
space in the memory and therefore better efficiency
 The function is called in the main program using function
name and appropriate parameters (if any)
 Example 3: In this example program from Example 2, to
indefinitely flash all LEDs on port 1 at a rate of 1 second is
rewritten using function to generate time delay
33
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW
#include <reg66x.h>
void DELAY(void);
void main(void)
{
for(;;)
{
P1 = 0xFF; /* Turn All LEDs ON */
DELAY(); /* Wait for 1 second */
P1 = 0x00; /* Turn All LEDs OFF */
DELAY();
}
}
void DELAY(void)
{
unsigned char i, j;
for(i=0; i<=255; i=i+1)
{
for(j=0; j<=255; j=j+1)
{
;
} 34
}
}
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW
viii. Other Loops in C
 Two other loops exist in C language - <do…while> and
<while>. Instructions to generate single loop delay using
those two loop techniques are given below
i=0;
do
{
i=i+1;
} while(i<=255);
i=0;
while(i<=255)
{
i=i+1;
}
35
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW
Example 4: Program from Examples 2 and 3 is rewritten and modified so that LEDs on port 1 flash with 1 s time
delay only 10 times.
#include <reg66x.h>
void DELAY(void);
void main(void)
{
unsigned char N;
N=0;
do
{
P1 = 0xFF; /* Turn All LEDs ON */
DELAY(); /* Wait for 1 second */
P1 = 0x00; /* Turn All LEDs OFF */
DELAY();
N=N+1;
} while(N<10);
}
void DELAY(void)
{
unsigned char i,j;
for(i=0; i<=255; i=i+1)
{
for(j=0; j<=255; j=j+1)
{
;
36
}
}
}
3.3 REPRESENTATION OF PROGRAMS AND THEIR EXECUTION FLOW

ix. Making Decisions in the Program


 An important feature of any embedded system is the ability
to test the value of any parameter in the system and based on
the outcome of this test take an appropriate action
 The parameter tested must be a program variable and C
construct usually employed to perform test is the <if>
statement - effect of this statement is illustrated on the
flowchart below

37
3.3 REPRESENTATION OF PROGRAMS AND
THEIR EXECUTION FLOW
 - C instructions to achieve this action are
if(condition)
{
Perform Action A
}
else
{
Perform Action B
}
x. ? Operator
 In the C program operator <?> can be used as a short hand
version of the ‘if’ statement discussed above.
 Flowchart and line of code provided below explain the effect
38
of using this operator
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW

oA = (B > C) ? X : Y; in other words “if B is greater than C


then let A=X otherwise let A=Y”
Example 5: Program to operate the LEDs attached to port 1 as a
BCD (Binary Coded Decimal) up counter. A BCD up counter is
one, which counts in binary from 0 to 9 and then repeats from 0
again
39
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW
#include <reg66x.h>
void DELAY(void);
void main(void)
{
unsigned char N=0;
for(;;)
{
P1 = N; /* Turn All LEDs ON */
DELAY(); /* Wait for a while */
N=N+1;
if(N>19)
{
N=0;
}
}
}
void DELAY(void)
{
unsigned char i,j;
for(i=0; i<=255; i=i+1)
{
for(j=0; j<=255; j=j+1)
{
; 40
}
}
}
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW
xi.Arrays
 Arrays are used when it is necessary to store larger number of
data of same type into consecutive memory locations where
they can easily be accessed by the program at some later stage
 As any other data in the program, array must be declared at the
beginning of the main program
 Upon reading this declaration compiler will reserve appropriate
number of memory locations to store the array elements
unsigned char T[20]
o This array declaration will cause the compiler to reserve 20
consecutive memory locations and call it T
o Note that number inside the square brackets indicates the size
41
of declared array
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW
Example 6: Two versions of the program that reads the state of the switches on port 0 and operates the LEDs on port
1 accordingly. For example if switch S0 is pressed, program will turn LED0 ON, if S2 and S3 are pressed, then
LED 2 and 3 must turn ON and so on.
// version 1
#include <reg66x.h>
void main(void)
{
for(;;)
{
P1=P0;
}
}
// version 2
#include <reg66x.h>
#define SWITCHES P0
#define LEDS P1
void main(void)
{
for(;;)
{
LEDS = SWITCHES; 42
}
}
FLOW
Example 7: This program monitors switch S0 attached to the pin 0 of port 0. When this switch is
pressed, it flashes the single LED attached to pin 0 of port 1 ten times. Previously discussed bit
masking technique is used to test the value of switch S0.
#include <reg66x.h>
#define ON 0x01
#define OFF 0x00
#define mask 0x01 // 00000001
void DELAY(void);
void main(void)
{
unsigned char S0;
unsigned char N;
for(;;)
{
S0=P0&mask; // masking bits
while(S0) // wait for key press
{
for(N=0;N<10;N++)
{
P1=ON;
DELAY();
P1=OFF;
DELAY();
}
S0=P0&mask;
}
}
}
void DELAY(void)
{
unsigned char i,j;
for(i=0; i<=255; i=i+1)
{
for(j=0; j<=255; j=j+1) 43
{
;
}
}
}
3.3 REPRESENTATION OF PROGRAMS AND THEIR
EXECUTION FLOW
 Another way to access a single pin on any port of 8051 is to
make use of special sbit data type.
 This data type provides access to bit-addressable SFRs and
bit-addressable memory space within the processor.
 Line: sbit S0=P0^0; creates an sbit type variable S0 that points
to pin 0 of port 0
 Using bit addressing ability of 8051 C compiler, alternative
version of the program can be written

44
3.3 REPRESENTATION OF PROGRAMS AND
THEIR EXECUTION FLOW
#include <reg66x.h>
#define ON 0xFF
#define OFF 0x00
sbit S0 = P0^0;
void DELAY(void);
void main(void)
{
unsigned char N;
for(;;)
{
while(S0)
{
for(N=0;N<10;N++)
{
P1=ON;
DELAY();
P1=OFF;
DELAY();
}
}
}
}
45

Note that because there is no way to indirectly address registers in the 8051, addresses for sbit
type variables must be declared outside of any functions within the code
3.4 FUNDAMENTALS OF ASSEMBLY LANGUAGE AND LINKING
 Although simpler to read than machine form, the code of
Figure 3.5, which is a pure assembly listing, still has
unfriendly notes.
 For example, the user needs the memory map to identify
addresses 0x0022 and 0x0021, and knowledge of machine
instruction lengths to know how many bytes the PC should
jump.
 A friendlier version is found in Figure 3.7, written with IAR
assembler syntax. This is part of a complete source file.
 Each line in the source file is a source statement.

46
3.4 FUNDAMENTALS OF ASSEMBLY LANGUAGE AND
LINKING

Figure 3.7 Assembly language code for Figure 3.4

47
Figure 3.8 Example of a list file line
3.4 FUNDAMENTALS OF ASSEMBLY LANGUAGE
AND LINKING
 Now assembly instructions have the format illustrated below;
only the original instruction fields, mnemonics and operands,
are compulsory.
 Mnemonics cannot start on the first column.

 In fact, every source statement has the same format, all fields
being in general optional.
 The mnemonics may be a machine instruction mnemonics or
a directive.
 Operands must always go after a mnemonic.

 Observe that the machine language and instruction


mnemonics have not changed
48
3.4 FUNDAMENTALS OF ASSEMBLY LANGUAGE
AND LINKING
 But now there are new features in the listing that make it
easier to read.
 Namely, we find comments, labels, symbolic names, and
directives.
 On the first column we can only have a comment (starting
with the semicolon), a label, a C-type preprocessor directive,
or a blank
 Assembling is done with a two pass assembler, which runs
over the source code more than once to resolve constants and
labels
 The assembler receives the source file and outputs an object f
ile, as well as other optional files
49
3.4 FUNDAMENTALS OF ASSEMBLY LANGUAGE AND LINKING

3.4.1 Directives
 Directives are for the assembler only

 They do not translate into machine code or data to be loaded


into the microcontroller memory
 They serve to organize the program, create labels and
symbolic names, and so on
 Directives depend on the assembler, but instructions belong
to the CPU architecture and are independent of the assembler
• Comments: Anything on a line after and including a semicolon (;)
is a comment
• Names: These are names given to numbers, expressions, hardware
devices, and so on
• Labels: These always start on the first column
• Directives EQU, #define, #include and ORG: The code example 50
of Figure 3.7 introduces some directives
3.4 FUNDAMENTALS OF ASSEMBLY
LANGUAGE AND LINKING
 Example 3.8 Even if the source file is not yet complete, let
us look at what happens when the assembly code of Figure
3.7 is processed.
 Labels DELAY and LED, as well as the symbolic name
COUNTER are identified as 50000 (=C350h), 1 (=01h), and
R15, respectively.
 All other symbolic names found, such as P1DIR and P1OUT,
are defined in the header file.
 For other labels, the value will be generated, and the ORG
directive allows us to understand the process.
 ORG 0F800h is used just before the beginning of the source
code
 Therefore the first machine language instruction 4031 0300 51
following the directive goes to that address, 0F800h
3.4 FUNDAMENTALS OF ASSEMBLY LANGUAGE
AND LINKING
 The result can be appreciated with the list file, as partially
illustrated below:

 The assembly listing has the label RESET for this first
instruction, so RESET becomes 0F800h.
 Similarly, the label StopWDT takes the value F804h, which
is the address where the instruction is stored.
 Every label attached to an instruction will be then assigned
the value of the corresponding instruction address.

52
3.4 FUNDAMENTALS OF ASSEMBLY LANGUAGE
AND LINKING
3.4.2 Labels in Instructions
o Always use a label for
 Entry statement of the main code and of an Interrupt Service
Routine (ISR). The label takes the value of the reset vector or
interrupt vector.
 Entry statement of a subroutine. The label can be used to call the
subroutine using it in immediate addressing mode in the call
instruction, for example call #Label.
 Instruction to which reference is made, for example for a jump.
 Labels are also useful as highlights for instructions, even if no
reference is needed
Example 3.9 Continuing with the same listing used in example
3.8, the reader can verify that the label Mainloop will be equal
to 0xF80E. The label is used for jump instructions and can be
53
used as any other integer constant with addressing modes as
illustrated next.
3.4 FUNDAMENTALS OF ASSEMBLY LANGUAGE
AND LINKING
 mov.w #Mainloop, R6 (immediate mode for Mainloop)
yields R6 = F80Eh. mov.w Mainloop,R6 (direct or symbolic
mode forMainloop) yields R6 = 403F.
 Call #Mainloop (immediate mode for Mainloop) calls a
subroutine with entry line at address 0xF80E. Hence, the
CPU pushes the PC onto the top of the stack (TOS) and then
loads it with 0xF80E.
 Call Mainloop (direct or symbolic mode for Mainloop) will
push the PC onto the TOS and load it with 0x403F.
 In this particular example, there will be an error since the
values at PC must be even. The CPU will reset.

54
3.4 FUNDAMENTALS OF ASSEMBLY LANGUAGE
AND LINKING
3.4.3 Source Executable Code
 The executable code is the set of CPU executable source
statements, namely, the instructions.
 It is the most important part of the source file.

 It consists of the main code and, optionally, subroutines and


Interrupt Service Routines. Important characteristics to consider are
i. Label for Entry line: Names like “RESET”, “INIT”, “START” are
common, but any one will do. This label serves to load the reset
vector.
ii. and peripherals configuration: This task includes
 stack initialization,
 configuration of the watchdog timer,
 configuration of peripherals and I/O ports as needed
iii. Main routine or algorithms: The instructions for the intended 55
program.
3.5 MAPPING TASKS IN COMPILATION
 When multiple tasks are mapped to the same processor, they
have to be scheduled to alternate their execution.
 Multi-task generation produces code that uses an underlying
multi-task engine in order to manage and schedule such
tasks.
 Two possible approaches for dynamic multitasking: RTOS-
based multi-tasking and interrupt-based multi-tasking
 The approach predominantly-used is RTOS-based multi-
tasking, in which user tasks are executed on top of an off-the-
shelf RTOS and scheduled by the RTOS scheduler.
 Sometimes performance and resource constraints hinder
using a complete RTOS. In such a case, an alternative of
interrupt-based multi-tasking can be applied 56

You might also like