home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ARM Club 3
/
TheARMClub_PDCD3.iso
/
hensa
/
programming
/
extasm_1
/
!extAOF
/
Manual
< prev
next >
Wrap
Text File
|
1995-07-08
|
14KB
|
426 lines
------------------------------------------------------------------------
extAOF version 1.60
------------------------------------------------------------------------
This program is to be used with extASM to produce files in AOF format.
It is Shareware (part of the extASM package).
© Terje Slettebø 1995
This program takes an assembly source for the extASM assembler and
translates it to a source which, when assembled, produces a file in the
ARM Object Format (AOF). This can then be linked with e.g. AOF files
from a C compiler.
The system is as follows:
____________ ___________
| C compiler | | Assembler | ... (other possible code
|____________| |___________| generators)
| |
____|_____ _____|____
| AOF file | | AOF file |
|__________| |__________|
| |
|_________________|
|
___|____
| Linker |
|________|
|
_____|______
| Executable |
| file |
|____________|
AOF files are also called object files. Since the linker doesn't care
where an object file comes from, you can use the object file, and
linker, system in different ways, e.g.
- You can just link object files from the C compiler. This is the normal
use when compiling a C program. The C compiler compiles the C program
and produces an AOF file in the 'O' directory. Then the linker links
together this AOF file and any other library files that are referenced,
e.g. RISC_OSLib, and makes an executable program.
- You can also link C and assembly by using extAOF to make an AOF file,
which can then be linked with one or more object files from the C
compiler.
To do this, do the following:
1. Convert the assembly source that you want to make into an AOF file,
with extAOF, and assemble the resulting source with extASM. You then
get an AOF file.
2. Put this AOF file somewhere where it can be used for linking. You
can e.g. have it in a directory together with the other object file
directories, such as CLib and RISC_OSLib. The files in the 'O'
subdirectories of these directories are the object files. The
placement of the object file is not important though.
You then have to inform the linker of the existence of the object
file. In ANSI C this can be done by appending the full pathname of
the AOF file in the 'Libraries' menu entry.
3. You also have to make a header file for any procedure you define,
to be included with the other header files.
E.g. for a procedure called 'testproc', which adds two numbers, and
returns the result, the header info could be as follows:
'extern int testproc(int,int);'
This can also be put in the C source.
When you then compile a C program, the relevant assembler part will be
linked in, if it is referenced in the C program by calling one
of the assembler routines. If you have an assembler routine with the
name 'procedure', then calling 'procedure(<any parameters>);' from a C
program will link it with the program. How assembler routines are set
up so as to be referenceable and callable is explained after the next
paragraph.
- Another way you can use the object file system is to perform a linking
just of assembler routines. This can be handy if you have a large
assembly source, and you only change a part of it. Then you can
pre-assemble the other parts as AOF files, and link them with the
routine you are working on. Then you don't have to assemble the whole
source every time. In this way, one source can call a routine or
reference a variable in another source, and the referencing is worked
out by the linker.
Object assembler statements
------------------------------------------------------------------------
There are some statements or keywords which can be included in the
assembly source, to enable extAOF to generate the AOF file, and define
any procedures or reference external procedures etc. These statements
are of course removed in the converted version of the source. The
statements used are based on studying the ObjAsm assembler output of
ANSI C, and should be fairly close to the Acorn ObjAsm syntax. I am not
sure that they are completely the same, though.
Some of the following information is obtained from the PRM's, in the
chapters about the ARM Object File Format, and ARM Procedure Call
Standard. If you want a more detailed description of the AOF format and
how to use it, you are referred to those chapters. It shouldn't be
necessary to know more than what is written in this file to be able to
use this program. The assembler source statements are as follows.
Statements
----------
In this description, 'symbol' is used to mean both global variable
(which can be referenced in other AOF files), and procedure.
Statements must be preceded by '#' (including the '%' statement)
just like the other commands in extASM. Statements can be written in
upper or lower case.
Mark an area
------------------------------------------------------------------------
#area <areaname> [,code|,noinit] [,readonly]
... (code, data or zero-initialised data)
#end
All code or data for an AOF file, as well as #import and #export statements,
has to be in an area. If a symbol in an area is referenced, then that area
is included in the final executable file. At the end of the area, you can
also use a new #area statement, instead of #end.
code
----
If 'code' is appended to the statement, it is a code-area, otherwise it
will be a data-area.
noinit
------
If you instead append 'noinit', then it will be treated as a non-
initialized data area, which should be zero-initialised.
The linker will then either allocate a pre-defined zero-initialised area, or
set up code to zero-initialise it at run time. This is up to the linker. It
seems that the linker with ANSI C uses the latter method, although I am
not sure about this.
The advantage of this 'noinit' option is that the object file can be much
smaller, since you don't have to include the zero-initialised data, you just
specify the size of the area, using the #% <size in bytes> statement in the
area.
readonly
--------
If you use the 'readonly' parameter, the code or data will be specified
as read-only, otherwise it will be read/write.
The linker will group all Read-Only areas together, and all Read/Write
areas and all Zero-Initialised areas. The Read-Only areas will also be
write-protected, if hardware permitted.
The linker will group the areas first by attribute (Read-Only etc.),
then by the (case-significant) alphabetical order of area names. The
Read-Only areas will preceed the Read/Write areas. Within Read-Only and
Read/Write areas, Code preceeds Data, which preceeds Zero-Initialised
data. Zero-Initialised data may not have the Read-Only attribute.
#import <Symbolname>
------------------------------------------------------------------------
Reference an external symbol. This symbol can then be used in the code
in two different ways:
B[L][CC] Symbol
This branch/branch with link will branch to the address of the routine
given by the symbol. 'cc' is the (optional) condition code.
DCD Symbol
This word will then contain the address of the symbol.
Examples:
---------
Calling an external procedure
-----------------------------
#import printf ; this is the name of the procedure to reference
BL printf
Reading or writing an external global variable
----------------------------------------------
#import SomeGlobalVar ; this is the name of the global variable to
; reference
.SomeGlobalAdr
DCD SomeGlobalVar ; this will contain the address of the global
... ; variable (e.g. one defined in a C program)
...
LDR R0,SomeGloalAdr ; read the address of the variable
LDR R1,[R0] ; read the value of the variable
#export <Symbolname>
------------------------------------------------------------------------
Define a symbol. This can then be referenced in an external object file.
Examples:
---------
Defining a procedure
--------------------
#export TestProc
.TestProc
ADD R0,R0,R1
MOVS R15,R14
Defining a global variable
--------------------------
#export testglobalvar
.testglobalvar
DCD 0 ; this is the initial value of the global variable.
Both #import and #export, as well as other code, as mentioned, have to
be in an area, defined with #area-#end.
#entry
------------------------------------------------------------------------
One of the areas in an object file may be designated as containing the
start address for the program, which is linked to include this file. If
so, the entry address can be specified with the above statement.
#% <Size>
------------------------------------------------------------------------
Set size of zero-initialised area in bytes.
Program operation
------------------------------------------------------------------------
To convert an assembly source to an AOF file, simply drag it to the
extAOF icon on the iconbar. The program will then open a save box, and
you can save the converted source again. This source then has to be
assembled, and this will produce the AOF file.
The process is like this:
Drag, or use Drag from
s-F10 in save box, or
StrongED use Autostart
________ _________ ___________ ___________
| extASM | | | | Converted | | extASM |
| source | -----> | extAOF | -----> | source | -----> | assembler |-
--
|________| |_________| |___________| |___________|
_______
| AOF |
--> | file |
|_______|
Menu items
----------
Autostart
---------
When this is selected, extAOF will automatically send the converted
source to extASM, if present. It will then produce the AOF file.
extAOF will save the converted source file as "ScrapFile", in the
process, and this will then be loaded by extASM. For this reason, don't
have any file called "ScrapFile" in the same directory as the assembly
source.
It is necessary to have the scrap file in the same directory as the
assembly source, as extASM uses the path of the file to determine the
directory to save the object file to.
Delete tempfile
---------------
When this is selected, extAOF will delete the file "ScrapFile", which is
made when using Autostart.
Save setup
----------
This will save the current setup, i.e. the Autostart and Delete tempfile
state.
You can also check the AOF files, by using the 'decaof' program, which
is supplied with ANSI C.
How to make linkable code
------------------------------------------------------------------------
When calling an external procedure, or when making a procedure that can
be referenced from another file, the register usage is as follows:
On entry to a procedure, the following statements should be true:
-----------------------------------------------------------------
Argument 1 is in R0
Argument 2 is in R1
Argument 3 is in R2
Argument 4 is in R3
Argument 5 and onwards are stored on the stack (R13).
All integer and pointer arguments are passed as 32-bit words. All
floating point arguments are passed as 64-bit values, in two words (as
stored by the 'STFD' instruction).
On exit from a procedure, the following statements should be true:
------------------------------------------------------------------
R4-R11, and F4-F7 should contain the same values that they did at the
instant of the call. If the procedure returns a word-sized result, which
is not a floating point value, then it should be in R0. If the procedure
returns a floating point result, then it should be in F0.
Examples of linkable code:
--------------------------
C header
--------
extern int AddNum(int,int); /* This just adds two numbers and returns
the result */
/*
The AOF files contain no information about whether a symbol is a
procedure or a variable, so this has to be declared, either in the
C source, or in a header file.
*/
Code for procedure
------------------
#area AddNumArea,code
#export AddNum
.AddNum
ADD R0,R0,R1 ; Argument 1 and 2 are in registers R0 and R1.
; Return result in R0.
MOVS R15,R14 ; Return from procedure. Use the 'S' suffix to
; Preserve the flags.
#end
It is as easy as this!
If you use any other registers than R0-R3 or R12, or F0-F3, then these
have to be preserved on the stack at the start of the procedure (the R13
is set up as a stack), and restored when returning. Se the entry/exit
conditions for a procedure described above.
Code for procedure, which also calls an external procedure
----------------------------------------------------------
C header
--------
extern void TestProc(void);
Code for procedure
------------------
#area TestProcArea,code
#export TestProc
#import printf
.TestProc
STMFD R13!,{R4,R14} ; R4 is used, so it has to be stored on the stack
ADR R0,TextStr
MOV R1,#1
MOV R2,#2
MOV R3,#3
MOV R4,#4
BL printf
LDMFD R13!,{R4,R15}^ ; use the '^' suffix to preserve the flags.
.textstr
DCB "This is a test, var1=%d, var2=%d, var3=%d, var4=%d\n",0
ALIGN
#end
Known bugs
----------
#entry doesn't work yet.
Since extASM has its own DDEUtils-emulator module ("Sender"), to be able to
support Throwback, then only ANSI C's !CC application or extASM can be run
at one time, if making AOF files.
This is because the extASM's Sender module, and !CC's DDEUtils module
clashes. I havn't found any fix for this at the moment.
To make AOF files, load extASM (if not loaded) and assemble the AOF file.
Then quit extASM and load !CC, to use the AOF file for linking with C. To
assemble the AOF file again, quit !CC and load extASM. This process is done
relatively easy with two Obey files (e.g. "RunAsm" and "RunC").
Any questions, suggestions, bugs etc. are welcome. I can be contacted as
follows:
Programmers BBS (Norway), +22 71 41 07 / +22 71 51 07, or email:
terje.slettebo@programmers.bbs.no