ARM development
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 and utilities 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 object file format. 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.
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%
Note:
The variable, <yymmdd>, indicates
the release date found on the CD.
Assume the
release is installed in C:\CYGNUS.
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 (for example,
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 (coff).
The third part is the generic tool name (gcc). For example, the
GCC compiler for the ARM7 is arm-coff-gcc and the GCC compiler
for the ARM7T is thumb-coff-gcc.
The ARM7/7T package includes the following
supported tools.
|
|
|
|
|
|
|
|
|
|
GCC compiler |
|
|
|
|
C++ compiler |
|
|
|
|
GNU assembler |
|
|
|
|
GNU LD linker |
|
|
|
|
Standalone simulator |
|
|
|
|
Binary utilities |
arm-coff-nm
arm-coff-objcopy
arm-coff-objdump
arm-coff-ranlib
arm-coff-size
arm-coff-strings
arm-coff-strip |
thumb-coff-nm
thumb-coff-objcopy
thumb-coff-objdump
thumb-coff-ranlib
thumb-coff-size
thumb-coff-strings
thumb-coff-strip |
|
|
GDB debugger |
|
|
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 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-coff-gcc
and thumb-coff-gcc specific
command-line options that are supported.
arm-coff-gcc
options
The following
options are specific to the arm-coff-gcc configuration.
-mapcs-frame
Generate a stack frame upon entry to a function, as defined
in the ARM Procedure Calling Standard.
-mno-apcs-frame
Do not generate a stack frame upon entry to a function.
The 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. This is the default setting.
-mapcs-32
Produce assembly code which conforms to the 32 bit version
of the ARM Procedure Calling Standard. This is the 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. This is the default setting.
-mapcs-reentrant
Produce assembly code that is position independent and
reentrant.
-mno-apcs-rentrant
Do not produce position independent, reentrant assembly
code. This is the 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. This is the default setting.
-mfpe
Floating point instructions should be emulated by the
ARM Floating Point Emulator code, which is supplied by the operating system.
-mfpe=N
Floating point instructions should be emulated by the
ARM Floating Point Emulator code version, N. Valid version
numbers are 2 and 3. 2 is the default setting.
-msoft-float
Floating point instructions should be emulated by library
calls. This is the 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. This is the 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. This is the default setting.
-msched-prolog
Allow instructions in function prologues to be rearranged
to improve performance. This is the 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 variable, XXXX, can be one of the following
processors.
-
arm2
-
arm250
-
arm3
-
arm6
(arm6 is the default setting.)
-
arm600
-
arm610
-
arm620
-
arm7
-
arm7m
-
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 variable, XXXX, can
be one of the following architectures.
-
armv2
-
armv2a
-
armv3
(armv3 is the default setting)
-
armv3m
-
armv4
-
armv4t
thumb-coff-gcc
options
The following
options are specific to the thumb-coff-gcc configuration.
-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.
This is the 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). This
is the 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. This is the 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 targets
The following
arm-coff-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 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
-
-
-
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
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 because 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
r0 only 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 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, in the following format.
< name >, < register number >
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
The assembler supports
the following synthesized instructions (pseudo instructions, which correspond
to two or more actual machine 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
# 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. 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.ld
must be specified at compilation. To activate this mode in GDB type
target sim '. 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 command
target remote <devicename> 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 ' load '. 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 continue '.
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); }
Create the following
sample source code and save it as thumb_stuff.c '.
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 thub_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.