The GNUPro Toolkit
from Cygnus is a complete solution for C and C++ development for the ARM7/7T
processor using both the 32-bit ARM instruction-set and the 16-bit THUMB
instruction-set extensions. The tools include the compiler, interactive
debugger, utilities and libraries. Debugger and linker support is also
included for the PID Series Evaluation board.
The following documentation discusses
cross-development with the ARM processors.
GNUPro Toolkit features for
ARM targets
The following
documentation describes ARM7-specific features of the GNUPro Toolkit.
ARM7 and ARM7T
processors are the supported hosts.
The
following targets are supported for ARM targets.
-
GNUPro Instruction Set Simulator
-
PID Series Evaluation board
Both big-endian
and little-endian mode may be selected. The default is little endian.
The following table shows the hosts supported
by ARM targets.
The ARM7 tools support
the COFF and ELF object file formats. See Chapter 4, System V Application
Binary Interface (Prentice Hall, 1990). Use ld (see Using
ld
in GNUPro Utilities) or objcopy (see Using
binutils
in GNUPro Utilities) to produce S-records.
For
the Windows 95/NT toolchain the libraries are installed in different locations.
Therefore, the Windows 95/NT hosted toolchain requires environmental settings
to function properly, as designated in the following example’s declaration
(the variable, <yymmdd>, indicates the release date
found on the CD).
SET PROOT=C:\cygnus\arm-<yymmdd>
SET PATH=%PROOT%\H-i386-cygwin32\BIN;%PATH%
SET INFOPATH=%PROOT%\info
REM Set TMPDIR to point to a ramdisk if you have one
SET TMPDIR=%PROOT%
The following strings
are case sensitive under UNIX and Windows NT.
-
Command line options
-
Assembler labels
-
Linker script commands
-
Section names
The following
strings are not case sensitive under UNIX or Windows NT:
-
GDB commands
-
Assembler instructions and register
names
File names
are
case sensitive under UNIX. Case sensitivity
for Windows NT is dependent on system configuration. By default, file names
under Windows NT are not case sensitive.
Cross-development
tools in the Cygnus GNUPro Toolkit normally have names that reflect the
target processor and the object file format output by the tools (ELF or
COFF). This makes it possible to install more than one set of tools in
the same binary directory, including both native and cross-development
tools.
The complete
tool name is a three-part hyphenated string. The first part indicates either
a 32-bit ARM tool (arm), or a 16-bit THUMB tool (thumb).
The second part indicates the file format output by the tool (elf
or coff). The third part is the generic tool name (gcc).
For example, the GCC compiler for the ARM7 is either ‘arm-elf-gcc’
or ‘arm-coff-gcc’ and the GCC compiler for the ARM7T is either
‘thumb-elf-gcc’ or ‘thumb-coff-gcc’.
The ARM7/7T package includes the following
supported tools.
|
|
|
|
|
|
|
GCC compiler |
|
thumb-coff-gcc
thumb-elf-gcc
|
|
C++ compiler |
|
thumb-coff-c++
thumb-elf-c++
|
|
GNU assembler |
|
thumb-coff-as
thumb-elf-as
|
|
GNU LD linker |
|
thumb-coff-ld
thumb-elf-ld
|
|
Standalone simulator |
|
thumb-coff-run
thumb-elf-run
|
|
Binary utilities |
arm-coff-nm
arm-elf-nm
arm-coff-objcopy
arm-elf-objcopy
arm-coff-objdump
arm-elf-objdump
arm-coff-ranlib
arm-elf-ranlib
arm-coff-size
arm-elf-size
arm-coff-strings
arm-elf-strings
arm-coff-strip
arm-elf-strip |
thumb-coff-ar
thumb-elf-ar
thumb-coff-nm
thumb-elf-nm
thumb-coff-objcopy
thumb-elf-objcopy
thumb-coff-objdump
thumb-elf-objdump
thumb-coff-ranlib
thumb-elf-ranlib
thumb-coff-size
thumb-elf-size
thumb-coff-strings
thumb-elf-strings
thumb-coff-strip
thumb-elf-strip |
|
GDB debugger |
arm-coff-gdb
arm-coff-gdb
|
thumb-coff-gdb
thumb-elf-gdb
|
The binaries
for a Windows NT hosted toolchain are installed with the .exe
suffix. However, the .exe suffix does not need to be specified
when running the executable.
The GNUPro
Toolkit supports communication with the ARM7 PID board, using GDB to communicate
with the Embedded ICE interface, which is connected to the ARM 7 PID board.
Connecting to the ARM7 PID target
Use the following
instructions to connect the ARM7 PID (process ID) board. The
ARM PID board gets its power from a PC AT power supply, using the P8 and
P9 connectors. The Embedded ICE interface box requires a 9V DC 500 mA power
supply with a center-positive connector, one of which should have been
provided with the Embedded ICE board.
To
establish a serial connection, use the following process.
1. Connect
the serial port.
The Embedded ICE board needs
to connect to the serial port of the host computer, which will be running
GDB. A serial cable is supplied with the Embedded ICE. It has three connectors,
the one labeled ARM connects to the Embedded ICE, the other two provide
the option of connecting to either a Sun type (DB25) serial port or a PC
type (DB 9) serial port, and they are labeled as such. Only one of these
can be used at a time. Embedded ICE comes with a short ribbon cable, which
has a 14-pin header connector on each end. One end connects to the port
on the front of the Embedded ICE box. The other end connects to port PL1
on the ARM 7 processor daughtercard.
2.
Test the serial connection.
Run GDB on the host computer.
Type target rdi <serial port> where <serial
port> is the name of the serial port to which the Embedded ICE
connects. Examples are /dev/ttya on a UNIX system or com1
on a PC. This should return a few lines of information about the version
of the Embedded ICE. The following output is an example of the initialization.
(gdb) target rdi /dev/com3
|
EmbeddedICE Manager (ADP, ARM7TDI) 2.02 (Advanced RISC Machines SDT 2.10)
|
Connected to ARM RDI target.
|
At
this point, use GDB commands normally. If a GDB error message is returned,
try resetting the Embedded ICE box by pressing the small red button on
the front, then checking all power and cable connections as well as the
host computer port configuration. For testing purposes, if you use a program
to monitor the serial port to which the Embedded ICE is connected, you
will see the version information that the Embedded ICE emits on the serial
line every time it is powered up or reset.
Compiler
issues for ARM and THUMB targets
The following
documentation describes ARM7 and ARM7T-specific features of the GNUPro
Compiler. For a list of available generic compiler options, see GNU
CC command options in Using
GNU CC in GNUPro Compiler Tools. In addition, the
following documentation describes the ARM and THUMB
specific command-line options that are supported.
The following
options are specific to the arm-coff-gcc and arm-elf-gcc configurations.
-mapcs-frame
Generate a stack frame upon entry to a function, as defined
in the ARM Procedure Calling Standard (APCS).
-mno-apcs-frame
Do not generate a stack frame upon entry to a function.
The APCS (APCS) specifies that the generation of stack frames is
optional, hence this pair of options. Not generating stack frames produces
slightly smaller and faster code. Default setting.
-mapcs-32
Produce assembly code which conforms to the 32 bit version
of the ARM Procedure Calling Standard. Default setting.
-mapcs-26
Produce assembly code which conforms to the 26 bit version
of the ARM Procedure Calling Standard, as used by earlier versions of the
ARM processor (ARM2, ARM3).
-mapcs-stack-check
Produce assembly code which checks the amount of stack
space available upon entry to a function and which calls a suitable function
if their is insufficient space available.
-mno-apcs-stack-check
Do not produce code to check for stack space upon entry
to a function. Default setting.
-mapcs-reentrant
Produce assembly code that is position independent and
reentrant.
-mno-apcs-rentrant
Do not produce position independent, reentrant assembly
code. Default setting.
-mshort-load-bytes
Two byte values should be loaded by performing two individual
byte loads and then merging the results. This allows shorts to be loaded
from non-aligned addresses without generating a memory access fault.
-mno-short-load-bytes
Two byte values should be loaded using the most space
efficient method. On an ARM processor that supports half word loads these
instructions will be used. Default setting.
-mfpe
Floating point instructions should be emulated by the
ARM Floating Point Emulator code, which is supplied by the operating system.
-msoft-float
Floating point instructions should be emulated by library
calls. Default setting.
-mhard-float
Floating point instructions can be performed in hardware.
-mbig-endian
Produce assembly code which is targeted for a big endian
processor.
-mlittle-endian
Produce assembly code which is targeted for a little
endian processor. Default setting.
-mwords-little-endian
Produce assembly code which is targeted for a big endian
processor, but which stores words in a little endian format. This is for
backward compatibility with older versions of GCC.
-mthumb-interwork
Produce assembly code which supports calls between the
ARM instruction set and the THUMB instruction set.
-mno-thumb-interwork
Do not produce code specifically intended to support
calling between ARM and THUMB instruction sets. Default setting.
-msched-prolog
Allow instructions in function prologues to be rearranged
to improve performance. Default setting.
-mno-sched-prolog
Do not allow the instructions in function prologues to
be rearranged. This guarantees that function prologues will have a well-defined
form, depending upon their nature.
-mcpu=XXXX
Produce assembly code specifically for the indicated
processor. The ‘XXXX’ variable can be one of the following
processors.
-
arm2
-
arm250
-
arm3
-
arm6
-
arm600
-
arm610
-
arm620
-
arm7
-
arm7m (the default setting)
-
arm7d
-
arm7dm
-
arm7di
-
arm7dmi
-
arm70
-
arm700
-
arm700i
-
arm710
-
arm710c
-
arm7100
-
arm7500
-
arm7500fe
-
arm7tdmi
-
arm8
-
strongarm
-
strongarm110
-march=XXXX
Produce assembly code specifically for an ARM processor
of the indicated architecture. The ‘XXXX’ variable can
be one of the following architectures.
-
armv2
-
armv2a
-
armv3
-
armv3m
-
armv4 (the default setting)
-
armv4t
The following
options
are specific to the thumb-coff-gcc and thumb-elf-gcc
configurations.
-mtpcs-frame
Generate a stack frame upon entry to a non-leaf function,
as defined in the THUMB Procedure Calling Standard (tpcs). A leaf
function is one which does not call any other function.
-mno-tpcs-frame
Do not generate a stack frame upon entry to a non-leaf
function. The THUMB Procedure Calling Standard (tpcs) specifies
that the generation of stack frames is optional, hence this pair of options.
Default setting.
-mtpcs-leaf-frame
Generate a stack frame upon entry to a leaf function,
as defined in the THUMB Procedure Calling Standard (tpcs).
-mno-tpcs-leaf-frame
Do not generate a stack frame upon entry to a leaf function,
as defined in the THUMB Procedure Calling Standard (tpcs). Default
setting.
-mbig-endian
Produce assembly code which is targeted for a big endian
processor.
-mlittle-endian
Produce assembly code which is targeted for a little
endian processor. Default setting.
-mthumb-interwork
Produce assembly code which supports calls between the
ARM instruction set and the THUMB instruction set.
-mno-thumb-interwork
Do not produce code specifically intended to support
calling between ARM and THUMB instruction sets. If such calls are used,
they will probably fail. This is the default setting.
Preprocessor
symbols for ARM and THUMB targets
The following
arm-coff-gcc
and arm-elf-gcc specific preprocessor symbols are supported.
|
|
|
|
|
|
|
If -mapcs-26
has
not
been
specified.
|
|
If -mapcs-26
has
been specified.
|
|
If -mhard-float
has
not
been
specified.
|
|
If -mwords-little-endian
has
been specified.
|
|
If -mbig-endian
has
been specified.
|
|
If -mbig-endian
has
not
been
specified.
|
|
If -mcpu=arm2
has
been specified.
|
|
If -mcpu=arm250
has
been specified.
|
|
If -mcpu=arm3
has
been specified.
|
|
If -mcpu=arm6
has
been specified.
|
|
If -mcpu=arm60
has
been specified.
|
|
If -mcpu=arm600
has
been specified.
|
|
If -mcpu=arm610
has
been specified.
|
|
If -mcpu=arm620
has
been specified.
|
|
If -mcpu=arm7
has
been specified.
|
|
If -mcpu=arm7m
has
been specified.
|
|
If -mcpu=arm7d
has
been specified.
|
|
If -mcpu=arm7dm
has
been specified.
|
|
If -mcpu=arm7di
has
been specified.
|
|
If -mcpu=arm7dmi
has
been specified.
|
|
If -mcpu=arm70
has
been specified.
|
|
If -mcpu=arm700
has
been specified.
|
|
If -mcpu=arm700i
has
been specified.
|
|
If -mcpu=arm710
has
been specified.
|
|
If -mcpu=arm710c
has
been specified.
|
|
If -mcpu=arm7100
has
been specified.
|
|
If -mcpu=arm7500
has
been specified.
|
|
If -mcpu=arm7500fe
has
been specified.
|
|
If -mcpu=arm7tdmi
has
been specified.
|
|
If -mcpu=arm8
has
been specified.
|
|
If -mcpu=strongarm
has
been specified.
|
|
If -mcpu=strongarm110
has
been specified.
|
The following
thumb-coff-gcc
and thumb-elf-gcc specific preprocessor symbols are supported.
|
|
|
|
|
|
|
If -mbig-endian
has
been specified.
|
|
If -mbig-endian
has
not
been specified.
|
|
If -mbig-endian
has
been specified.
|
|
If -mbig-endian
has
not
been specified.
|
ARM7/7T-specific
attributes
ABI
summary for ARM targets
The ARM7 tools
adhere by default to the APCS (ARM Procedure Call Standard). The ARM7T
tools adhere to the TPCS (THUMB Procedure Call Standard). The following
documentation of the ABI is consistent with both these standards.
Data
types sizes and alignments for ARM targets
The following
table shows the size and alignment for all data types.
Data types and
size alignment for ARM targets
The following
information is necessary for specifying data type sizes and alignment for
ARM targets.
-
Alignment within aggregates (structs
and unions) is as above, with padding added if needed
-
Aggregates have alignment equal
to that of their most aligned member
-
Aggregates have sizes which are
a multiple of their alignment
Subroutine
calls for ARM targets
The following
lists describe the calling conventions for subroutine calls.
Structures
that are less than or equal to 32 bits in length are passed as values.
Structures
that are greater than 32 bits in length are passed as pointers.
The
stack frame for ARM targets
The following
documentation describes ARM stack frames.
-
The stack grows downwards from
high addresses to low addresses.
-
A leaf function need not allocate
a stack frame if it does not need one.
-
A frame pointer need not be allocated.
-
The stack pointer shall always
be aligned to 4 byte boundaries.
-
The stack pointer always points
to the lowest addressed word currently stored on the stack.
See ARM
stack frames for functions that take a fixed number of arguments for
an illustartion of how stack frames for functions appear that take a fixed
number of arguments.
See ARM
stack frames for functions that take a variable number of arguments
for an illustration of how stack frames appear for functions that take
a variable number of arguments.
C
language calling conventions for ARM targets
A floating-point
value occupies one, two, or three words, as appropriate to its type. Floating
point values are encoded in IEEE 754 format, with the most significant
word of a double having the lowest address.
When targetting
little-endian ARMs, the words that make up a double will be stored in big-endian
order, while the bytes inside each word will be stored in little-endian
order..
The C compiler
widens arguments of type float to type double to support inter-working
between ANSI C and classic C.
Char, short,
pointer and other integral values occupy one word in an argument list.
Character and short values are widened by the C compiler during argument
marshalling.
A structure
always occupies an integral number of words (unless this is overridden
by the -mstructure-size-boundry command line option).
Argument values
are collated in the order written in the source program The first four
words of the argument values are loaded into r0 through r3',
and the remainder are pushed on to the stack in reverse order (so that
arguments later in the argument list have higher addresses than those earlier
in the argument list). As a consequence, a FP value can be passed in integer
registers, or even split between an integer register and the stack.
Function
return values for ARM targets
The following
documentation describes how different data types are returned.
Floats and
integer-like values are returned in register r0 '.
A type is integer-like
if its size is less than or equal to one word and if the type is a structure,
union or array, then all of its addressable sub-fields must have an offset
of zero. For example, the following example's declaration is integer-like
in form.
struct {int a:8, b:8, c:8, d:8;}
The following
example's declaration is similar.
union {int i; char*p;}
However, the
following declaration is unlike the previous example declarations since
it is possible to take the address of fields B, C or D, and their offsets
from the start of the structure are not zero.
struct {char A; char B; char c; char D;}
Doubles and
long
long integers are returned in registers r0 and
r1.
For doubles r0 always contains the most significant word of the
double. For long long ' values
r0only contains the most
significant word if the target is
big-endian. All other values are returned by placing them
into a suitably sized area of memory provided for this purpose by the function's
caller. A pointer to this area of memory is passed to the function as a
hidden first argument, generated at compile time like the following example’s
declaration.
LargeType t;
t = func(arg);
The previous
declaration is implemented in a manner similarly to the following example’s
declaration.
LargeType t;
(void) func(&t,arg);
Assembler
issues for ARM targets
The following
documentation describes ARM7/7T-specific features of the GNUPro assembler.
The ARM7/7T
syntax is based on the syntax in ARM’s ARM7 Architecture Manual.
For a list
of available generic assembler options, see Command-line
options in Using as
in
GNUPro Utilities. The following are ARM7/7T specific assembler
command-line options.
-m[arm][1|2|250|3|6|7[t][d][m][i]]
Select processor variant.
Select architecture variant.
Only allow THUMB instructions.
Select the v1.0 floating point architecture.
Select the v1.1 floating point architecture.
Don’t allow floating-point multiple instructions.
Don’t allow any floating-point instructions.
Mark the assembled code as supporting inter-working.
Mark the code as supporting the 26 bit variant of the
ARM Procedure calling standard. This is the default.
Mark the code as supporting the 26 bit variant of the
ARM Procedure calling standard.
Assemble code for a big endian CPU.
Assemble code for a little endian CPU. This is the default.
Assembler comments
start with the @ (‘at’ symbol) and extend to the end of the line.
Register names
for the ARM7/7T targets
The following
lists the register names supported for the ARM7/7T, using the ‘register
name, register number’ format.
APCS
names for the general registers
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Floating
point support for ARM targets
The assembler
supports hardware floating point, but the compiler does not.
Opcodes
for ARM targets
For detailed
information on the ARM7/7T machine instruction set, see ARM7 Series Instruction
Manual. The GNU Assembler (GAS) implements all the standard opcodes.
Synthetic
Instructions for ARM targets
Synthesized
instructions are pseudo instructions that correspond to two or more actual
machine instructions. The GNU assembler supports the following synthesized
instructions.
The following code uses the ARM instruction set.
The following code uses the THUMB instruction set.
The following code uses the THUMB instruction set, and
should be assembled even if the target processor does not support THUMB
instructions.
The following label is the name of function which has
been encoded using THUMB instructions, rather than ARM instructions.
ARM7/7T-specific
assembler error messages
Error: Unrecognized
opcode
This instruction is misspelled or there is a syntax error
somewhere.
Warning: operand
out of range
An immediate value was specified that is too large for
the instruction
Linker issues for
ARM targets
The following
documentation describes ARM7/7T-specific features of the GNUPro linker.
For a list of available generic linker options, see Linker
scripts in Using ld
in
GNUPro Utilities.
Linker
script for ARM targets
The GNU linker
uses a linker script to determine how to process each section in an object
file, and how to lay out the executable. The linker script is a declarative
program consisting of a number of directives. For instance, the ENTRY()directive
specifies the symbol in the executable that will be the executable's entry
point. For a complete description of the linker script, see Linker
scripts in Using ld
in
GNUPro Utilities.
For the ARM7/7T
tools, there are two linker scripts, one to be used when compiling for
the simulator and one to be used when compiling for the evaluation board.
The following
script is the sim.ld linker script for the simulator for ARM targets
using COFF object file format.
# Linker script for ARM COFF.
# Based on i386coff.sc by Ian Taylor <ian@cygnus.com>.
test -z "$ENTRY" && ENTRY=_start
if test -z "${DATA_ADDR}"; then
if test "$LD_FLAG" = "N" || test "$LD_FLAG" = "n"; then
DATA_ADDR=.
fi
fi
cat <<EOF
OUTPUT_FORMAT("${OUTPUT_FORMAT}","${BIG_OUTPUT_FORMAT}","${LITTLE_OUTPUT_FORMAT}")
${LIB_SEARCH_DIRS}
ENTRY(${ENTRY})
SECTIONS
{
/* We start at 0x8000 because gdb assumes it (see FRAME_CHAIN).
This is an artifact of the ARM Demon monitor using the bottom 32k
as workspace (shared with the FP instruction emulator if
present): */
.text ${RELOCATING+ 0x8000} : {
*(.init)
*(.text)
*(.glue_7t)
*(.glue_7)
*(.rdata)
${CONSTRUCTING+ ___CTOR_LIST__ = .; __CTOR_LIST__ = . ;
LONG (-1); *(.ctors); *(.ctor); LONG (0); }
${CONSTRUCTING+ ___DTOR_LIST__ = .; __DTOR_LIST__ = . ;
LONG (-1); *(.dtors); *(.dtor); LONG (0); }
*(.fini)
${RELOCATING+ etext = .;}
}
.data ${RELOCATING+${DATA_ADDR-0x40000 + (. & 0xfffc0fff)}} : {
${RELOCATING+ __data_start__ = . ;}
*(.data)
${RELOCATING+ __data_end__ = . ;}
${RELOCATING+ edata = .;}
${RELOCATING+ _edata = .;}
}
.bss ${RELOCATING+ SIZEOF(.data) + ADDR(.data)} :
{
${RELOCATING+ __bss_start__ = . ;}
*(.bss)
*(COMMON)
${RELOCATING+ __bss_end__ = . ;}
}
${RELOCATING+ end = .;}
${RELOCATING+ _end = .;}
${RELOCATING+ __end__ = .;}
.stab 0 ${RELOCATING+(NOLOAD)} :
{
[ .stab ]
}
.stabstr 0 ${RELOCATING+(NOLOAD)} :
{
[ .stabstr ]
}
}
EOF
Debugger
issues for ARM targets
The following
documentation describes ARM7/7T-specific features of the GNUPro debugger,
GDB. There are two ways for GDB to talk to an ARM7/7T target. Each target
requires that the program be compiled with a target specific linker script.
-
Simulator
GDB's built-in software simulation of the ARM7 processor
allows the debugging of programs compiled for the ARM7/7T without requiring
any access to actual hardware. For this target the linker script sim.ldmust
be specified at compilation. To activate this mode in GDB, type
target
sim and then load the code into the simulator by typing load and
debug it in the normal fashion.
-
Remote target board
For this target the linker script eval.ld must
be specified at compilation. To connect to the target board in GDB, using
the
target remote <devicename>
command, where <devicename> will be a serial device
such as /dev/ttya (UNIX) or
com2 (Windows NT). Then load
the code onto the target board by typing the load command. After
being downloaded, the program can be executed.
When using
the remote target, GDB does not accept the run command. However,
since downloading the program has the side effect of setting the PC to
the start address, you can start your program by typing the continue
command.
For the available
generic debugger options, see Debugging
with GDB in GNUPro Debugging Tools. There are no
ARM7/7T-specific debugger command-line options.
Simulator
issues for ARM targets
The simulator
supports the following registers.
|
|
|
|
|
|
|
sp,
pc,
ccr,
mdr,
lar,
lir
|
Memory is 256K
bytes starting at location 0. The stack starts at the highest memory address
and works downward. The heap starts at the lowest address after the text,
data and bss.
There are no
ARM7/7T-specific simulator command-line options.
Reducing code size on the ARM 7/7T
The ARM7/7T processor supports two different
instruction sets. It can run the standard ARM instruction set, where each
instruction occupies 32 bits, and also the reduced size THUMB instruction
set, where each instruction occupies 16 bits. THUMB instructions are more
limited in what they can do compared to ARM instructions, but they can
represent a considerable saving in the amount of space occupied by the
instructions. It is possible to dynamically switch between the two instruction
sets, thus gaining the advantages of both.
The GNUPro compilers are able to produce code for both
the ARM and THUMB instruction sets, but only at a file level of granularity.
Thus the programmer can choose whether individual functions should be encoded
as either ARM or THUMB instructions, but they cannot specify that specific
parts of a function should be ARM or THUMB. The other parts of the GNUPro
tools (the assembler and linker and so on), all support mixing ARM and
THUMB code at any level.
The GNUPro toolkit has two compilers, one of which produces
ARM assembler, and the other produces THUMB assembler. If the programmer
wants to use just one instruction set to compile their program then no
special procedures need to be followed, other than selecting the correct
compiler. If the programmer wants to use both instruction sets in their
program, then they must separate the ARM and THUMB parts of their program
into separate files and compile each individually, while also specifiying
the -mthumb-interwork command line flag. When the assembled object
files are linked together the linker will generate special code to switch
between the two instruction sets whenever a call is made from an ARM function
to a THUMB function or vice versa.
Create the following sample source code and save it as
arm_stuff.c
.
extern int thumb_func (int);
int main (void) { return 7 + thumb_func (7); }
int thumb_func (int arg) { return arg + 7; }
2. Compile and link from source code.
First compile the ARM sample code with the following
declaration.
arm-coff-gcc -g -c -O2 -mthumb-interwork arm_stuff.c
Then
compile the THUMB sample code with the following declaration.
THUMB-coff-gcc -g -c -O2 -mthumb-interwork THUMB_stuff.c
Then
link with the following declaration.
arm-coff-gcc arm_stuff.o thumb_stuff.o -o program
The
use of the
-g and -O2 command line options are optional.
They are used in the previous examples to make the output of the debugger
easier to understand.
Run
on the stand-alone Simulator for ARM 7/7T targets
The following script example shows how
to set up the stand-alone simulator for the ARM7/7T targets.
C:\> arm-coff-gdb program
|
GNU gdb 4.16-armT-970630
|
Copyright 1997 Free Software Foundation, Inc.GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions.
|
Type "show copying" to see the conditions. This version of GDB is supported for customers of Cygnus Solutions. Type "show warranty" for details. This GDB was configured as "--host=i686-pc-linux-gnu
|
--target=arm-acorn-coff"...
|
|
(gdb) target sim
|
Connected to the simulator.
|
|
(gdb) load
|
Loading section .text, size 0x8e8 lma 0x8000
|
Loading section .data, size 0x2fc lma 0x408e8
|
Start address 0x8000
|
Transfer rate: 24352 bits in <1 sec.
|
|
(gdb) break main
|
Breakpoint 1 at 0x8048: file arm_stuff.c, line 2.
|
|
(gdb) break thumb_func
|
Breakpoint 2 at 0x8060: file thumb_stuff.c, line 1.
|
|
(gdb) run
|
Starting program: /elmo/scratchme/nickc/work/released/arm/gcc/tests/program
|
|
Breakpoint 1, 0x8048 in main () at arm_stuff.c:2
|
2 int main (void) { return 7 + thumb_func (7); }
|
|
(gdb) disassemble
|
Dump of assembler code for function main:
|
0x803c <main>: mov ip, sp
|
0x8040 <main+4>: stmdb sp!, {fp, ip, lr, pc}
|
0x8044 <main+8>: sub fp, ip, #4
|
0x8048 <main+12>: bl 0x8124 <__gccmain>
|
0x804c <main+16>: mov r0, #7
|
0x8050 <main+20>: bl 0x88b0 <__thumb_func_from_arm>
|
0x8054 <main+24>: add r0, r0, #7
|
0x8058 <main+28>: ldmdb fp, {fp, sp, lr}
|
0x805c <main+32>: bx lr
|
End of assembler dump.
|
|
(gdb) continue
|
Continuing.
|
|
Breakpoint 2, thumb_func (arg=7) at thumb_stuff.c:1
|
1 int thumb_func (int arg) { return 7 + arg; }
|
|
(gdb) disassemble
|
Dump of assembler code for function thumb_func:
|
0x8060 <thumb_func>: 3007 add r0, #7
|
0x8062 <thumb_func+2>: 4770 bx lr
|
End of assembler dump.
|
|
(gdb) quit
|
The program is running. Quit anyway (and kill it)? (y or n) y
|
Note:
The ARM add instruction at <main+24>
occupies 4 bytes, whereas the THUMB add instruction at <thumb_func>
occupies 2 bytes.