Linking Separately Assembled
“Relocatable” Assembly Files
Up to this point in the course, we have been working with
“
Absolute Assembly
” programs where all code is put into one file,
and it is assembled at absolute addresses indicated with “ORG”
statements.
•
The need for separately assembly-language modules, which are
separately assembled into object files, and then finally linked together
into a single executable file, may not be very apparent in this course,
where our applications are relatively short and simple.
•
However, in large software development efforts, where several
programmers are involved, it is often more convenient for each
programmer to develop and maintain their own separate program file
which is eventually linked with other programmer’s program files into
an executable program.
•
This approach also shortens compile time, since only the faulty module
XREF Statement
•
“
XREF variable_list
”
This (XREF => Externally Referenced) statement must appear at the
beginning of any file that references variables or program locations that
are NOT defined in that file. Each of these externally referenced
variables or program locations must be listed following the XREF
keyword.
•
We often say that XREF is used to
IMPORT
variables from other files.
•
XREF is a promise made by the programmer to the linker that the
variables listed can be found in one of the other files that are to be
linked with this one.
XDEF Statement
•
“
XDEF variable_list
”
This (XDEF => Externally Defined) statement must appear at the beginning of
any file that declares variables or program locations (such as subroutine
names) defined in that file that must be externally referenced by code found
in other files. Each of these locally defined variables or program locations
must follow the XDEF keyword.
•
We often say that XDEF is used to
EXPORT locally defined variables and
program locations
to other files.
•
XDEF is needed to tell the linker that the listed variables or program locations
will need to be accessed by at least one other file that is to be linked with this
one.
•
Example:
The Linker Parameter File (.PRM)
•
Applications containing relocatable sections must be linked.
The linker parameter file must contain at least:
–
The name of the executable file produced by the linker.
–
The name of the object file(s) which should be linked.
–
The specification of a memory area where the sections containing
variables must be allocated.
–
The specification of a memory area where the sections containing
code or constants must be allocated.
–
The specification of the application's entry point.
Example of linking three relocatable files
together
•
The first file is named “main.asm”, and it contains a main
program that flashes an LED on and off at a 2-second rate.
•
This main program file “main.asm” calls a timer delay
routine located in a second (separate) file, called
“timer.asm”. This timer routine is called from “main.asm”
by loading the time to wait in a dedicated RAM location
defined back in main.asm file.
•
The “main.asm” file also calls a routine in a third separate
Steps in setting up the relocatable assembly
project using HC(S)12 CodeWarrior
•
First open CodeWarrior, and click
File – New – HC(S)12 New Project Wizard
•
Enter Project name and desired path
•
Click OK and Next
•
Enter “MC9S12C128” and Next
•
Check “Assembly”, uncheck “C” and Next
•
Check both “Full-Chip Simulation” and also “P&E Multilink
Cyclone Pro” and Finish.
•
Once this “relocatable assembly” project is created, expand
“PRM”. This contains the linker parameter files that were
created for both the simulator and also for the BDM
download/debugger pod. Select (double left click on) the
“
P&E_Multilink_Cyclone_Pro_linker.prm” file
.
•
Also expand “Sources” and examine the example
•
This linker parameter file was automatically
generated to link the example relocatable
“main.asm” program that was also
automatically generated.
•
The linked file is then downloaded onto the
CSM12C128 module via the P&E USB BDM
in-circuit background debugging pod that is
Note the following lines in the .PRM linker
parameter file:
•
NAMES END
•
SEGMENTS
RAM = READ_WRITE 0x400 to 0x0FFF
(The address range for the 3k RAM block on the 9S12C128 processor
is specified by this line.)
ROM_4000 =READ_ONLY 0x4000 to 0x7FFF
ROM_C000=READ_ONLY 0xC000 to 0xFEFF
(The address ranges for the two 16 kbyte flash ROM (for program
and read-only data) are specified by these lines.)
•
PLACEMENT
_PRESTART,
STARTUP,
ROM_VAR,
STRINGS,
VIRTUAL_TABLE_SEGMENT,
NON_BANKED,
COPY
INTO ROM_C000 /* or ROM_4000*/
_SSTACK
•
STACKSIZE 0x100
(this sets the stack segment size to 0x100 bytes, which should
be way more than most programs require. You should
change this if you need a larger stack.)
•
VECTOR 0 Entry
INIT Entry
(This initializes the reset vector (Vector 0) in assembly
programs. The symbol “Entry” corresponds to the symbolic
starting address (entry point) of the main.asm program.
If
If your ASM file uses interrupts, you will need to initialize the
necessary interrupt vectors just under where the reset vector (Vector
0) is initialized.
•
Note that “Vector 0” (Reset Vector) corresponds to the first entry
in the interrupt table shown on the next slide.
•
For example, if you want to initialize the Timer Channel 2 (TC2)
interrupt vector, to point to an interrupt routine named “TC2_ISR”
you would enter the following two lines at the end of the file:
Vector 10 TC2_ISR
•
IF there are interrupts, also add “ROM_4000” to the
DEFAULT_ROM line of linker PRM file:
Vector 0
Vector 3
Vector 10
•
Now click on the “main.asm” file so that it
is displayed in the right window. Erase
the sample file that was automatically
generated, and enter the following
; export symbols (to be referenced outside of this file)
XDEF Entry
XDEF Timer_word
; import symbols (defined outside of this file)
XREF __SEG_END_SSTACK
XREF WAITMS
XREF INIT_PLL
INCLUDE 'mc9s12c128.inc'
MyCode: SECTION
Entry:
LDS #__SEG_END_SSTACK ; Initialize the stack pointer
BSET DDRT,$02 ; Make PT1 AN OUTPUT (LED on PT1)
JSR INIT_PLL ; Routine INIT_PLL is in another file
MOVW #1000,Timer_word
FLASHAGN: BSET PTT,$02 ; TURN ON LED
JSR WAITMS ; Routine WTMS is in another file
; Waits number of ms in location
BCLR PTT,$02 ; “Timer_word”
JSR WAITMS
Adding the INIT_PLL.asm File
•
Now click on
File – New Text File
and enter the following INIT_PLL code on the next slide.
•
When you are done, save the file in your project’s “Sources”
folder, where main.asm is already saved; be sure to name
the file in some meaningful way, giving it an .ASM file
extension, such as “INIT_PLL.asm”
•
Now right click on the “Sources” heading in the left “Project
; export symbols (to be referenced outside of this file)
XDEF INIT_PLL
INCLUDE 'mc9s12c128.inc'
MyCode: SECTION
INIT_PLL:
;Initialize clock generator and PLL to increase CPU clock speed by factor of 6
PLL_init bclr CLKSEL,$80 ;Disconnect PLL from system if connected.
bset PLLCTL,$40 ;Turn on the PLL hardware block.
movb #5,SYNR
;Set PLL multiplier
movb #0,REFDV
;Set PLL divider
;From Section 3.1.1 of CRG Block Guide
;PLLCLK = OSCCLK*(SYNR+1)/(REFDV+1)
; = 4 MHz * (5+1)/(0+1) = 24 MHz
nop
;NOP delays put here to allow time for
nop
nop
;CRGFLG flag register to become valid.
wt_PLL_Lock:
brclr CRGFLG, 8, wt_PLL_Lock
;Wait here for PLL to “Lock in”
Adding the WTMS.asm file
•
Do this in the same way you added the
INIT_PLL file.
;
export symbols to be referenced outside of this file
XDEF WAITMS
; import external symbols to be referenced inside this file
XREF Timer_word
INCLUDE 'mc9s12c128.inc'
MY_EXTENDED_RAM: SECTION
TEMPWD: DS.W 1
MyCode: SECTION
WAITMS: PSHY
PSHX
LDY Timer_word
OUTERLOOP: MOVW #5000,TEMPWD
INNERLOOP: LDX TEMPWD
DEX
STX TEMPWD
BNE INNERLOOP
DEY
Resulting Linker Map File created after
Making this Project:
PROGRAM "C:\Documents and Settings\hoover\Desktop\ECE331
Lecture 6. Relocatable Assembly Modules\reloc_assembly_2009\
bin\P&E_Multilink_CyclonePro.abs"
********************************************
TARGET SECTION
---
---Processor : Freescale HC12
Memory Model: SMALL
FILE SECTION
--
---main.asm.o
Model: SMALL, Lang: Assembler
INIT_PLL.ASM.o Model: SMALL, Lang: Assembler
WAITMS.ASM.o Model: SMALL, Lang: Assembler
STARTUP SECTION
--
*****************************************************
**************************************** SECTION-ALLOCATION SECTION
Section Name Size Type From To Segment
---.init 32 R 0xC000 0xC01F ROM_C000
.stack 256 R/W 0x400 0x4FF RAM MyCode 53 R 0x388000 0x388034 PAGE_38 MY_EXTENDED_RAM 4 R/W 0x500 0x503 RAM .vectSeg0_vect 2 R 0xFFFE 0xFFFF .vectSeg0
Summary of section sizes per section type: READ_ONLY (R): 57 (dec: 87) READ_WRITE (R/W): 104 (dec: 260)
********************************************************************************************* VECTOR-ALLOCATION SECTION
Address InitValue InitFunction
0xFFFE 0xC000 Entry
********************************************************************************************* OBJECT-ALLOCATION SECTION
Name Module Addr hSize dSize Ref Section RLIB -MODULE: main.asm.o
--- PROCEDURES:
- PROCEDURES:
INIT_PLL 388000 13 19 1 MyCode wt_PLL_Lock 388013 8 8 0 MyCode - VARIABLES:
MODULE: WAITMS.ASM.o --- PROCEDURES:
WAITMS 38801B 5 5 2 MyCode OUTERLOOP 388020 6 6 0 MyCode INNERLOOP 388026 F 15 0 MyCode - VARIABLES:
TEMPWD 502 2 2 3 MY_EXTENDED_RAM
********************************************************************************************* MODULE STATISTIC
Name Data Code Const
main.asm.o 2 32 0
INIT_PLL.ASM.o 0 27 0 WAITMS.ASM.o 2 26 0 other 256 2 0
********************************************************************************************* SECTION USE IN OBJECT-ALLOCATION SECTION
---SECTION: ".init"
Entry FLASHAGN SECTION: "MyCode"
INIT_PLL wt_PLL_Lock WAITMS OUTERLOOP INNERLOOP SECTION: "MY_EXTENDED_RAM"
********************************************************************************************* OBJECT LIST SORTED BY ADDRESS
Name Addr hSize dSize Ref Section RLIB Timer_word 500 2 2 2 MY_EXTENDED_RAM TEMPWD 502 2 2 3 MY_EXTENDED_RAM Entry C000 10 16 0 .init
FLASHAGN C010 10 16 0 .init INIT_PLL 388000 13 19 1 MyCode wt_PLL_Lock 388013 8 8 0 MyCode WAITMS 38801B 5 5 2 MyCode OUTERLOOP 388020 6 6 0 MyCode INNERLOOP 388026 F 15 0 MyCode
********************************************************************************************* UNUSED-OBJECTS SECTION ---********************************************************************************************* COPYDOWN SECTION ---********************************************************************************************* OBJECT-DEPENDENCIES SECTION ---Entry USES __SEG_END_SSTACK INIT_PLL Timer_word
FLASHAGN USES WAITMS WAITMS USES Timer_word OUTERLOOP USES TEMPWD INNERLOOP USES TEMPWD
Making and Downloading this program
onto the CSMB9S12C128
•
LED on PT1 blinks at a 2 second rate
•
Commenting out the JSR INIT_PLL and remaking and
downloading results in an LED on PT1 that blinks at
a 24 second rate, because the bus clock has now
been lowered from