3.1.3 Projects with Additional Libraries
3.2 Command Line Options
3.2.1 Processor Selection Options
- 3.2.2 Path, Lib and Define Options
- 3.2.3 MCS51 Options
- 3.2.4 Optimization Options
- 3.2.5 DS390 Options
- 3.2.6 Other Options
- 3.2.7 Intermediate Dump Options
- 3.3 MCS51 Storage Class Language Extensions
+ 3.2.2 Preprocessor Options
+ 3.2.3 Linker Options
+ 3.2.4 MCS51 Options
+ 3.2.5 Optimization Options
+ 3.2.6 DS390 Options
+ 3.2.7 Other Options
+ 3.2.8 Intermediate Dump Options
+ 3.3 MCS51/DS390 Storage Class Language Extensions
3.3.1 xdata
3.3.2 data
3.3.3 idata
3.4 Pointers
3.5 Parameters & Local Variables
3.6 Overlaying
- 3.7 Critical Functions
- 3.8 Absolute Addressing
- 3.9 Interrupt Service Routines
- 3.10 Startup Code
- 3.11 Inline Assembler Code
- 3.12 int(16 bit) and long (32 bit ) Support
- 3.13 Floating Point Support
- 3.14 MCS51 Memory Models
- 3.15 Flat 24 bit Addressing Model
- 3.16 Defines Created by the Compiler
+ 3.7 Interrupt Service Routines
+ 3.8 Critical Functions
+ 3.9 Naked Functions
+ 3.10 Functions using private banks
+ 3.11 Absolute Addressing
+ 3.12 Startup Code
+ 3.13 Inline Assembler Code
+ 3.14 int(16 bit) and long (32 bit ) Support
+ 3.15 Floating Point Support
+ 3.16 MCS51 Memory Models
+ 3.17 Flat 24 bit Addressing Model
+ 3.18 Defines Created by the Compiler
4 SDCC Technical Data
4.1 Optimizations
4.1.1 Sub-expression Elimination
4.5 Global Registers used for Parameter Passing
4.5.1 Assembler Routine(non-reentrant)
4.5.2 Assembler Routine(reentrant)
- 4.6 With --noregparms Option
- 4.6.1 Assembler Routine Non-reentrant
- 4.6.2 Assembler Routine(reentrant)
- 4.7 External Stack
- 4.8 ANSI-Compliance
- 4.9 Cyclomatic Complexity
+ 4.6 External Stack
+ 4.7 ANSI-Compliance
+ 4.8 Cyclomatic Complexity
5 TIPS
6 Retargetting for other MCUs.
7 SDCDB - Source Level Debugger
the back-end SDCC uses a global register allocation scheme
which should be well suited for other 8 bit MCUs. The peep
hole optimizer uses a rule based substitution mechanism
-which is MCU independent. Supported data-types are short
-(8 bits, 1 byte), char (8 bits, 1 byte), int (16 bits, 2
-bytes ), long (32 bit, 4 bytes) & float (4 byte IEEE). The
-compiler also allows inline assembler code to be embedded
-anywhere in a function. In addition routines developed in
-assembly can also be called. SDCC also provides an option
-to report the relative complexity of a function, these functions
-can then be further optimized, or hand coded in assembly
-if need be. SDCC also comes with a companion source level
-debugger SDCDB, the debugger currently uses ucSim a freeware
-simulator for 8051 and other micro-controllers. The latest
-version can be downloaded from [http://sdcc.sourceforge.net/].
+which is MCU dependent. Supported data-types are char (8
+bits, 1 byte), short and int (16 bits, 2 bytes ), long (32
+bit, 4 bytes) and float (4 byte IEEE). The compiler also
+allows inline assembler code to be embedded anywhere in
+a function. In addition routines developed in assembly can
+also be called. SDCC also provides an option to report the
+relative complexity of a function, these functions can then
+be further optimized, or hand coded in assembly if needed.
+SDCC also comes with a companion source level debugger SDCDB,
+the debugger currently uses ucSim a freeware simulator for
+8051 and other micro-controllers. The latest version can
+be downloaded from [http://sdcc.sourceforge.net/].
1.2 Open Source
discuss SDCC with other SDCC users. Web links to other SDCC
related sites can also be found here. This document can
be found in the DOC directory of the source package as a
-text or HTML file. Some of the other tools(simulator and
+text or HTML file. Some of the other tools (simulator and
assembler) included with SDCC contain their own documentation
and can be found in the source distribution. If you want
the latest unreleased software, the complete source package
a message about not finding sdcc program, then you need
to check over your installation. Make sure that the sdcc
bin directory is in your executable search path defined
-by the PATH environment setting(see the Trouble-shooting
+by the PATH environment setting (see the Trouble-shooting
section for suggestions). Make sure that the sdcc program
is in the bin folder, if not perhaps something did not install
correctly.
SDCC binaries are commonly installed in a directory arrangement
like this:
+
+--------------------------------+-------------------------------------------+
| /usr/local/bin | Holds executables(sdcc, s51, aslink, ...) |
+--------------------------------+-------------------------------------------+
in the following test.c program using your favorite editor:
main()
-{ int i;
+{
+
+int i;
+
i = 0;
+
i += 10;
}
The next step is to try it with the linker. Type in "sdcc
test.c". If all goes well the compiler will link with
the libraries and produce a test.ihx output file. If this
-step fails(no test.ihx, and the linker generates warnings),
+step fails (no test.ihx, and the linker generates warnings),
then the problem is most likely that sdcc cannot find the
-usr/local/share/sdcc/lib/small directory(see the Install
-trouble-shooting section for suggestions).
+/usr/local/share/sdcc/lib directory (see the Install trouble-shooting
+section for suggestions).
The final test is to ensure sdcc can use the standard header
files and libraries. Edit test.c and change it to the following:
#include <string.h>
main()
-{ char str1[10];
+{
+
+char str1[10];
+
strcpy(str1, "testing");
+
}
+
Compile this by typing: "sdcc test.c".
This should generate a test.ihx output file, and it should
give no warnings such as not finding the string.h file.
If it cannot find the string.h file, then the problem is
that sdcc cannot find the /usr/local/share/sdcc/include
-directory(see the Install trouble-shooting section for suggestions).
+directory (see the Install trouble-shooting section for
+suggestions).
2.4 Install Trouble-shooting
2.4.2 SDCC does not compile correctly.
-A few things to try include starting from scratch by unpacking
-the .tgz source package again in an empty directory. If
-this doesn't work, you could try downloading a different
-version. If this doesn't work, you can re-direct the install
-messages by doing the following:
+A thing to try is starting from scratch by unpacking the
+.tgz source package again in an empty directory. Confure
+it again and build like:
-$./make > dump.txt 2>&1
+"make 2&>1 | tee make.log"
-After this you can examine the dump.txt files to locate the
-problem. Or these messages can be attached to an email that
-could be helpful when requesting help from the mailing list.
+After this you can review the make.log file to locate the
+problem. Or a relevant part of this be attached to an email
+that could be helpful when requesting help from the mailing
+list.
2.4.3 What the "./configure"
does
2.8.5 SDCDB - Source Level Debugger
-SDCDB is the companion source level debugger . The current
+SDCDB is the companion source level debugger. The current
version of the debugger uses Daniel's Simulator S51, but
can be easily changed to use other simulators.
* sourcefile.map - The memory map for the load module, created
by the Linker.
-* sourcefile.<ihx | s19> - The load module : ihx - Intel
- hex format (default ), s19 - Motorola S19 format when
- compiler option --out-fmt-s19 is used.
+* sourcefile.ihx - The load module in Intel hex format (you
+ can select the Motorola S19 format with --out-fmt-s19)
+
+* sourcefile.cdb - An optional file (with --debug) containing
+ debug information.
3.1.2 Projects with Multiple Source Files
sure you include the -L <library-path> option to tell the
linker where to look for these files. Here is an example,
assuming you have the source file 'foomain.c' and a library
-'foolib.lib' in the directory 'mylib'.
+'foolib.lib' in the directory 'mylib' (if that is not the
+same as your current project).
sdcc foomain.c foolib.lib -L mylib
-mtlcs900h Generate code for the Toshiba TLCS-900H processor(In
development, not complete).
-3.2.2 Path, Lib and Define Options
+3.2.2 Preprocessor Options
--I<path> The additional location where the pre processor
+-I<path> The additional location where the pre processor
will look for <..h> or "..h"
files.
-D<macro[=value]> Command line definition of macros. Passed
to the pre processor.
+--compile-only(-c) will compile and assemble the source,
+but will not call the linkage editor.
+
+3.2.3 Linker Options
+
--lib-path(-L) <absolute path to additional libraries> This
-option is passed to the linkage editor, additional libraries
+option is passed to the linkage editor's additional libraries
search path. The path name must be absolute. Additional
-library files may be specified in the command line . See
+library files may be specified in the command line. See
section Compiling programs for more details.
-3.2.3 MCS51 Options
+--xram-loc<Value> The start location of the external ram,
+default value is 0. The value entered can be in Hexadecimal
+or Decimal format, e.g.: --xram-loc 0x8000 or --xram-loc
+32768.
+
+--code-loc<Value> The start location of the code segment
+, default value 0. Note when this option is used the interrupt
+vector table is also relocated to the given address. The
+value entered can be in Hexadecimal or Decimal format, e.g.:
+--code-loc 0x8000 or --code-loc 32768.
+
+--stack-loc<Value> The initial value of the stack pointer.
+The default value of the stack pointer is 0x07 if only register
+bank 0 is used, if other register banks are used then the
+stack pointer is initialized to the location above the highest
+register bank used. eg. if register banks 1 & 2 are used
+the stack pointer will default to location 0x18. The value
+entered can be in Hexadecimal or Decimal format, eg. --stack-loc
+0x20 or --stack-loc 32. If all four register banks are used
+the stack will be placed after the data segment (equivalent
+to --stack-after-data)
+
+--stack-after-data This option will cause the stack to be
+located in the internal ram after the data segment.
+
+--data-loc<Value> The start location of the internal ram
+data segment, the default value is 0x30.The value entered
+can be in Hexadecimal or Decimal format, eg. --data-loc
+0x20 or --data-loc 32.
+
+--idata-loc<Value> The start location of the indirectly addressable
+internal ram, default value is 0x80. The value entered can
+be in Hexadecimal or Decimal format, eg. --idata-loc 0x88
+or --idata-loc 136.
+
+3.2.4 MCS51 Options
--model-large Generate code for Large model programs see
section Memory Models for more details. If this option is
section Memory Models for more details. This is the default
model.
---model-flat24 Generate code forDS80C390 24-bit flat mode.
-See section Memory Models for more details.
-
--stack-auto All functions in the source file will be compiled
as reentrant, i.e. the parameters and local variables will
be allocated on the stack. see section Parameters and Local
external ram for allocating variables and passing parameters.
See section on external stack for more details.
-3.2.4 Optimization Options
+3.2.5 Optimization Options
--nogcse Will not do global subexpression elimination, this
option may be used when the compiler creates undesirably
--noinvariant Will not do loop invariant optimizations, this
may be turned off for reasons explained for the previous
-option . For more details of loop optimizations performed
+option. For more details of loop optimizations performed
see section Loop Invariants.It recommended that this option
NOT be used , #pragma NOINVARIANT can be used to turn off
invariant optimizations for a given function only.
--noloopreverse Will not do loop reversal optimization
---noregparms By default the first parameter is passed using
-global registers (DPL,DPH,B,ACC). This option will disable
-parameter passing using registers. NOTE: if your program
-uses the 16/32 bit support routines (for multiplication/division)
-these library routines will need to be recompiled with the
---noregparms option as well.
-
-3.2.5 DS390 Options
+3.2.6 DS390 Options
--stack-auto See MCS51 section for description.
+--model-flat24 Generate 24-bit flat mode code. This is the
+one and only that the ds390 code generator supports right
+now and is default when using -mds390. See section Memory
+Models for more details.
+
--stack-10bit This option generates code for the 10 bit stack
-mode of the Dallas DS80C390 part. In this mode, the stack
-is located in the lower 1K of the internal RAM, which is
-mapped to 0x400000. Note that the support is incomplete,
-since it still uses a single byte as the stack pointer.
-This means that only the lower 256 bytes of the potential
-1K stack space can actually be used. However, this does
-allow you to reclaim the precious 256 bytes of low RAM for
-use for the DATA and IDATA segments. The compiler will not
-generate any code to put the processor into 10 bit stack
-mode. It is important to ensure that the processor is in
-this mode before calling any re-entrant functions compiled
-with this option. In principle, this should work with the
---stack-auto option, but that has not been tested. It is
-incompatible with the --xstack option. It also only makes
-sense if the processor is in 24 bit contiguous addressing
-mode (see the --model-flat24 option).
-
-3.2.6 Other Options
+mode of the Dallas DS80C390 part. This is the one and only
+that the ds390 code generator supports right now and is
+default when using -mds390. In this mode, the stack is located
+in the lower 1K of the internal RAM, which is mapped to
+0x400000. Note that the support is incomplete, since it
+still uses a single byte as the stack pointer. This means
+that only the lower 256 bytes of the potential 1K stack
+space will actually be used. However, this does allow you
+to reclaim the precious 256 bytes of low RAM for use for
+the DATA and IDATA segments. The compiler will not generate
+any code to put the processor into 10 bit stack mode. It
+is important to ensure that the processor is in this mode
+before calling any re-entrant functions compiled with this
+option. In principle, this should work with the --stack-auto
+option, but that has not been tested. It is incompatible
+with the --xstack option. It also only makes sense if the
+processor is in 24 bit contiguous addressing mode (see the
+--model-flat24 option).
+
+3.2.7 Other Options
--callee-saves function1[,function2][,function3].... The
compiler by default uses a caller saves convention for register
from larger functions. This option can be used to switch
the register saving convention for the function names specified.
The compiler will not save registers when calling these
-functions, extra code will be generated at the entry & exit
-for these functions to save & restore the registers used
-by these functions, this can SUBSTANTIALLY reduce code &
-improve run time performance of the generated code. In future
-the compiler (with interprocedural analysis) will be able
-to determine the appropriate scheme to use for each function
-call. DO NOT use this option for built-in functions such
-as _muluint..., if this option is used for a library function
-the appropriate library function needs to be recompiled
-with the same option. If the project consists of multiple
-source files then all the source file should be compiled
-with the same --callee-saves option string. Also see Pragma
-Directive CALLEE-SAVES. .
+functions, no extra code will be generated at the entry
+& exit for these functions to save & restore the registers
+used by these functions, this can SUBSTANTIALLY reduce code
+& improve run time performance of the generated code. In
+the future the compiler (with interprocedural analysis)
+will be able to determine the appropriate scheme to use
+for each function call. DO NOT use this option for built-in
+functions such as _muluint..., if this option is used for
+a library function the appropriate library function needs
+to be recompiled with the same option. If the project consists
+of multiple source files then all the source file should
+be compiled with the same --callee-saves option string.
+Also see Pragma Directive CALLEE-SAVES.
--debug When this option is used the compiler will generate
debug information , that can be used with the SDCDB. The
in the project should be compiled with this option. See
section Register Extension for more details.
---compile-only(-c) will compile and assemble the source
-only, will not call the linkage editor.
-
---xram-loc<Value> The start location of the external ram,
-default value is 0. The value entered can be in Hexadecimal
-or Decimal format .eg. --xram-loc 0x8000 or --xram-loc 32768.
-
---code-loc<Value> The start location of the code segment
-, default value 0. Note when this option is used the interrupt
-vector table is also relocated to the given address. The
-value entered can be in Hexadecimal or Decimal format .eg.
---code-loc 0x8000 or --code-loc 32768.
-
---stack-loc<Value> The initial value of the stack pointer.
-The default value of the stack pointer is 0x07 if only register
-bank 0 is used, if other register banks are used then the
-stack pointer is initialized to the location above the highest
-register bank used. eg. if register banks 1 & 2 are used
-the stack pointer will default to location 0x18. The value
-entered can be in Hexadecimal or Decimal format .eg. --stack-loc
-0x20 or --stack-loc 32. If all four register banks are used
-the stack will be placed after the data segment (equivalent
-to --stack-after-data)
-
---stack-after-data This option will cause the stack to be
-located in the internal ram after the data segment.
-
---data-loc<Value> The start location of the internal ram
-data segment, the default value is 0x30.The value entered
-can be in Hexadecimal or Decimal format .eg. --data-loc
-0x20 or --data-loc 32.
-
---idata-loc<Value> The start location of the indirectly addressable
-internal ram, default value is 0x80. The value entered can
-be in Hexadecimal or Decimal format .eg. --idata-loc 0x88
-or --idata-loc 136.
-
--peep-file<filename> This option can be used to use additional
rules to be used by the peep hole optimizer. See section
Peep Hole optimizations for details on how to write these
the `-E' option.
-MM Like `-M' but the output mentions only the user header
-files included with `#include file"'. System header files
-included with `#include <file>' are omitted.
+files included with `#include "file"'.
+System header files included with `#include <file>' are
+omitted.
-Aquestion(answer) Assert the answer answer for question,
in case it is tested with a preprocessor conditional such
-dN Like `-dD' except that the macro arguments and contents
are omitted. Only `#define name' is included in the output.
--S Stop after the stage of compilation proper; do not as-
-semble. The output is an assembler code file for the input
-file specified.
+-S Stop after the stage of compilation proper; do not assemble.
+The output is an assembler code file for the input file
+specified.
-Wa_asmOption[,asmOption]... Pass the asmOption to the assembler.
--Wl_linkOption[,linkOption] .. Pass the linkOption to the
+-Wl_linkOption[,linkOption]... Pass the linkOption to the
linker.
--int-long-reent Integer (16 bit) and long (32 bit) libraries
--main-return This option can be used when the code generated
is called by a monitor program. The compiler will generate
a 'ret' upon return from the 'main' function. The default
-option is to lock up i.e. generate a 'ljmp .' .
+option is to lock up i.e. generate a 'ljmp '.
--no-peep Disable peep-hole optimization.
--peep-asm Pass the inline assembler code through the peep
-hole optimizer. Can cause unexpected changes to inline assembler
-code , please go through the peephole optimizer rules defnied
-in file 'SDCCpeeph.def' before using this option.
+hole optimizer. This can cause unexpected changes to inline
+assembler code, please go through the peephole optimizer
+rules defined in the source file tree '<target>/peeph.def'
+before using this option.
--iram-size<Value> Causes the linker to check if the interal
ram usage is within limits of the given value.
-3.2.7 Intermediate Dump Options
+3.2.8 Intermediate Dump Options
The following options are provided for the purpose of retargetting
-and debugging the compiler . These provided a means to dump
+and debugging the compiler. These provided a means to dump
the intermediate code (iCode) generated by the compiler
in human readable form at various stages of the compilation
process.
---dumpraw . This option will cause the compiler to dump the
+--dumpraw This option will cause the compiler to dump the
intermediate code into a file of named <source filename>.dumpraw
just after the intermediate code has been generated for
-a function , i.e. before any optimizations are done. The
+a function, i.e. before any optimizations are done. The
basic blocks at this stage ordered in the depth first number,
so they may not be in sequence of execution.
---dumpgcse. Will create a dump if iCode, after global subexpression
+--dumpgcse Will create a dump of iCode's, after global subexpression
elimination, into a file named <source filename>.dumpgcse.
---dumpdeadcode .Will create a dump if iCode, after deadcode
+--dumpdeadcode Will create a dump of iCode's, after deadcode
elimination, into a file named <source filename>.dumpdeadcode.
---dumploop. Will create a dump if iCode, after loop optimizations,
+--dumploop Will create a dump of iCode's, after loop optimizations,
into a file named <source filename>.dumploop.
---dumprange. Will create a dump if iCode, after live range
+--dumprange Will create a dump of iCode's, after live range
analysis, into a file named <source filename>.dumprange.
---dumpregassign. Will create a dump if iCode, after register
-assignment , into a file named <source filename>.dumprassgn.
+--dumlrange Will dump the life ranges for all symbols
---dumpall. Will cause all the above mentioned dumps to be
-created.
+--dumpregassign Will create a dump of iCode's, after register
+assignment , into a file named <source filename>.dumprassgn.
-Note that the files created for the dump are appended to
-each time. So the files should be deleted manually , before
-each dump is created.
+--dumplrange Will create a dump of the live ranges of iTemp's
-When reporting bugs, it can be helpful to include these dumps
-along with the portion of the code that is causing the problem.
+--dumpall Will cause all the above mentioned dumps to be
+created.
-3.3 MCS51 Storage Class Language Extensions
+3.3 MCS51/DS390 Storage Class Language Extensions
In addition to the ANSI storage classes SDCC allows the following
MCS51 specific storage classes.
Variables declared with this storage class will be placed
in the extern RAM. This is the default storage class for
-Large Memory model .
+Large Memory model, e.g.:
-eg. xdata unsigned char xduc;
+xdata unsigned char xduc;
3.3.2 data
This is the default storage class for Small Memory model.
Variables declared with this storage class will be allocated
-in the internal RAM.
+in the internal RAM, e.g.:
-eg. data int iramdata;
+data int iramdata;
3.3.3 idata
Variables declared with this storage class will be allocated
into the indirectly addressable portion of the internal
-ram of a 8051 .
+ram of a 8051, e.g.:
-eg.idata int idi;
+idata int idi;
3.3.4 bit
This is a data-type and a storage class specifier. When a
variable is declared as a bit , it is allocated into the
-bit addressable memory of 8051.
+bit addressable memory of 8051, e.g.:
-eg.bit iFlag;
+bit iFlag;
3.3.5 sfr / sbit
Like the bit keyword, sfr / sbit signifies both a data-type
and storage class, they are used to describe the special
-function registers and special bit variables of a 8051.
-
-eg.
+function registers and special bit variables of a 8051,
+eg:
sfr at 0x80 P0; /* special function register P0 at location
0x80 */
-
sbit at 0xd7 CY; /* CY (Carry Flag) */
3.4 Pointers
point to any of the memory spaces of the 8051. In addition
to the explicit pointers, the compiler also allows a _generic
class of pointers which can be used to point to any of the
-memory spaces.
+memory spaces.
Pointer declaration examples.
internal ram */
data unsigned char * xdata p;
-
/* pointer physically in code rom pointing to data in xdata
space */
xdata unsigned char * code p;
-
/* pointer physically in code space pointing to data in code
space */
code unsigned char * code p;
Well you get the idea. For compatibility with the previous
version of the compiler, the following syntax for pointer
-declaration is also supported. Note the above examples will
-be portable to other commercially available compilers.
+declaration is still supported but will disappear int the
+near future.
unsigned char _xdata *ucxdp; /* pointer to data in external
ram */
unsigned char _idata *uccp; /*
pointer to upper 128 bytes of ram */
-All unqualified pointers are treated as 3 - byte '_generic'
-pointers. These type of pointers can also to be explicitly
-declared.
+All unqualified pointers are treated as 3-byte (4-byte for
+the ds390) '_generic' pointers. These type of pointers can
+also to be explicitly declared.
unsigned char _generic *ucgp;
internal RAM ( for small model) or external RAM (for Large
model). They can be placed on the stack either by using
the --stack-auto compiler option or by using the 'reentrant'
-keyword in the function declaration.
-
-eg
+keyword in the function declaration, e.g.:
-unsigned short foo( short i) reentrant {
+unsigned char foo( char i) reentrant
+{
...
}
When compiled with the default option (i.e. non-reentrant
), local variables can be assigned storage classes and absolute
-addresses.
+addresses, e.g.: (jwk: pending: this is obsolete and need
+a rewrite)
-eg
+unsigned char foo() {
+
+xdata unsigned char i;
+
+bit bvar;
+
+data at 0x31 unsiged char j;
-unsigned short foo() {
- xdata unsigned short i;
- bit bvar;
- data at 0x31 unsiged short j;
...
}
Parameters and Local variables of functions that contain
16 or 32 bit multiplication or division will NOT be overlayed
-since these are implemented using external functions.
-
-eg.
+since these are implemented using external functions, e.g.:
#pragma SAVE
#pragma NOOVERLAY
-void set_error( unsigned short errcd)
-{
- P3 = errcd;
+void set_error( unsigned char errcd)
+{
+
+P3 = errcd;
}
#pragma RESTORE
void some_isr () interrupt 2 using 1
-{
- ...
- set_error(10);
- ...
-}
-
-In the above example the parameter errcd for the function
-set_error would be assigned to the overlayable segment (if
-the #pragma NOOVERLAY was not present) , this could cause
-unpredictable runtime behavior. The pragma NOOVERLAY ensures
-that the parameters and local variables for the function
-are NOT overlayed.
-
-3.7 Critical Functions
+{
-A special keyword may be associated with a function declaring
-it as 'critical'. SDCC will generate code to disable all
-interrupts upon entry to a critical function and enable
-them back before returning . Note that nesting critical
-functions may cause unpredictable results.
+...
-eg
+set_error(10);
-int foo () critical
-{
-...
...
}
-The critical attribute maybe used with other attributes like
-reentrant.
-
-3.8 Absolute Addressing
-
-Data items can be assigned an absolute address with the at
-<address> keyword, in addition to a storage class.
-
-eg.
-
-xdata at 0x8000 unsigned char PORTA_8255 ;
-
-In the above example the PORTA_8255 will be allocated to
-the location 0x8000 of the external ram.
-
-Note that is this feature is provided to give the programmer
-access to memory mapped devices attached to the controller.
-The compiler does not actually reserve any space for variables
-declared in this way (they are implemented with an equate
-in the assembler), thus it is left to the programmer to
-make sure there are no overlaps with other variables that
-are declared without the absolute address, the assembler
-listing file (.lst) and the linker output files (<filename>.rst)
-and (<filename>.map) are a good places to look for such
-overlaps.
-
-Absolute address can be specified for variables in all storage
-classes.
-
-eg.
-
-bit at 0x02 bvar;
-
-The above example will allocate the variable at offset 0x02
-in the bit-addressable space. There is no real advantage
-to assigning absolute addresses to variables in this manner
-, unless you want strict control over all the variables
-allocated.
+In the above example the parameter errcd for the function
+set_error would be assigned to the overlayable segment (if
+the #pragma NOOVERLAY was not present) , this could cause
+unpredictable runtime behavior when called from an ISR.
+The pragma NOOVERLAY ensures that the parameters and local
+variables for the function are NOT overlayed.
-3.9 Interrupt Service Routines
+3.7 Interrupt Service Routines
SDCC allows interrupt service routines to be coded in C,
with some extended keywords.
(8051 specific) when generating code for this function.
Note that when some function is called from an interrupt
service routine it should be preceded by a #pragma NOOVERLAY
-(if it is not reentrant) . A special note here, int (16
-bit) and long (32 bit) integer division, multiplication
-& modulus operations are implemented using external support
-routines developed in ANSI-C, if an interrupt service routine
-needs to do any of these operations then the support routines
+(if it is not reentrant). A special note here, int (16 bit)
+and long (32 bit) integer division, multiplication & modulus
+operations are implemented using external support routines
+developed in ANSI-C, if an interrupt service routine needs
+to do any of these operations then the support routines
(as mentioned in a following section) will have to recompiled
using the --stack-auto option and the source file will need
to be compiled using the --int-long-rent compiler option.
adjust the interrupt vector table to the maximum interrupt
number specified.
+
+--------------+--------------+----------------+
| Interrupt # | Description | Vector Address |
+--------------+--------------+----------------+
+--------------+--------------+----------------+
-If the interrupt service routine is defined without a register
-bank or with register bank 0 (using 0), the compiler will
-save the registers used by itself on the stack (upon entry
-and restore them at exit), however if such an interrupt
+
+If the interrupt service routine is defined without 'using'
+a register bank or with register bank 0 (using 0), the compiler
+will save the registers used by itself on the stack (upon
+entry and restore them at exit), however if such an interrupt
service routine calls another function then the entire register
bank will be saved on the stack. This scheme may be advantageous
for small interrupt service routines which have low register
Calling other functions from an interrupt service routine
is not recommended avoid it if possible.
-3.10 Startup Code
+3.8 Critical Functions
+
+A special keyword may be associated with a function declaring
+it as 'critical'. SDCC will generate code to disable all
+interrupts upon entry to a critical function and enable
+them back before returning. Note that nesting critical functions
+may cause unpredictable results.
+
+eg:
+
+int foo () critical
+{
+...
+...
+}
+
+The critical attribute maybe used with other attributes like
+reentrant.
+
+3.9 Naked Functions
+
+A special keyword may be associated with a function declaring
+it as '_naked'. The '_naked' function modifier attribute
+prevents the compiler from generating prologue and epilogue
+code for that function. This means that the user is entirely
+responsible for such things as saving any registers that
+may need to be preserved, selecting the proper register
+bank, generating the 'return' instruction at the end, etc.
+Practically, this means that the contents of the function
+must be written in inline assembler. This is particularly
+useful for interrupt functions, which can have a large (and
+often unnecessary) prologue/epilogue. For example, compare
+the code generated by these two functions:
+
+data unsigned char counter;
+void simpleIterrupt(void) interrupt 1
+{
+
+counter++;
+}
+
+void nakedInterrupt(void) interrupt 2 _naked
+{
+
+_asm
+
+ inc _counter
+
+ reti
+; MUST explicitly include ret in _naked function.
+
+_endasm;
+}
+
+For an 8051 target, the generated simpleInterrupt looks like:
+
+_simpleIterrupt:
+
+push acc
+
+push b
+
+push dpl
+
+push dph
+
+push psw
+
+mov psw,#0x00
+
+inc _counter
+
+pop psw
+
+pop dph
+
+pop dpl
+
+pop b
+
+pop acc
+
+reti
+
+whereas nakedInterrupt looks like:
+
+_nakedInterrupt:
+
+inc _counter
+
+reti
+; MUST explicitly include ret(i) in _naked function.
+
+While there is nothing preventing you from writing C code
+inside a _naked function, there are many ways to shoot yourself
+in the foot doing this, and is is recommended that you stick
+to inline assembler.
+
+3.10 Functions using private banks
+
+The 'using' attribute (which tells the compiler to use a
+register bank other than the default bank zero) should only
+be applied to 'interrupt' functions (see note A below).
+This will in most circumstances make the generated ISR code
+more efficient since it will not have to save registers
+on the stack.
+
+The 'using' attribute will have no effect on the generated
+code for a non-'interrupt' function (but may occasionally
+be useful anyway([footnote] possible exception: if a function is called ONLY
+from 'interrupt' functions using a particular bank, it can
+be declared with the same 'using' attribute as the calling
+'interrupt' functions. For instance, if you have several
+ISRs using bank one, and all of them call memcpy(), it might
+make sense to create a specialized version of memcpy() 'using
+1', since this would prevent the ISR from having to save
+bank zero to the stack on entry and switch to bank zero
+before calling the function) ).
+(jwk: todo: I don't think this has been done yet)
+
+An 'interrupt' function using a non-zero bank will assume
+that it can trash that register bank, and will not save
+it. Since high-priority interrupts can interrupt low-priority
+ones on the 8051 and friends, this means that if a high-priority
+ISR 'using' a particular bank occurs while processing a
+low-priority ISR 'using' the same bank, terrible and bad
+things can happen. To prevent this, no single register bank
+should be 'used' by both a high priority and a low priority
+ISR. This is probably most easily done by having all high
+priority ISRs use one bank and all low priority ISRs use
+another. If you have an ISR which can change priority at
+runtime, you're on your own: I suggest using the default
+bank zero and taking the small performance hit.
+
+It is most efficient if your ISR calls no other functions.
+If your ISR must call other functions, it is most efficient
+if those functions use the same bank as the ISR (see note
+A below); the next best is if the called functions use bank
+zero. It is very inefficient to call a function using a
+different, non-zero bank from an ISR.
+
+3.11 Absolute Addressing
+
+Data items can be assigned an absolute address with the at
+<address> keyword, in addition to a storage class.
+
+eg.
+
+xdata at 0x8000 unsigned char PORTA_8255 ;
+
+In the above example the PORTA_8255 will be allocated to
+the location 0x8000 of the external ram.
+
+Note that is this feature is provided to give the programmer
+access to memory mapped devices attached to the controller.
+The compiler does not actually reserve any space for variables
+declared in this way (they are implemented with an equate
+in the assembler), thus it is left to the programmer to
+make sure there are no overlaps with other variables that
+are declared without the absolute address, the assembler
+listing file (.lst) and the linker output files (<filename>.rst)
+and (<filename>.map) are a good places to look for such
+overlaps.
+
+Absolute address can be specified for variables in all storage
+classes.
+
+eg.
+
+bit at 0x02 bvar;
+
+The above example will allocate the variable at offset 0x02
+in the bit-addressable space. There is no real advantage
+to assigning absolute addresses to variables in this manner
+, unless you want strict control over all the variables
+allocated.
+
+3.12 Startup Code
The compiler inserts a jump to the C routine _sdcc__external__startup()
at the start of the CODE area. This routine can be found
to setup hardware or perform some other critical operation
prior to static & global variable initialization.
-3.11 Inline Assembler Code
+3.13 Inline Assembler Code
SDCC allows the use of in-line assembler with a few restriction
as regards labels. All labels defined within inline assembler
The inline assembler code can contain any valid code understood
by the assembler (this includes any assembler directives
-and comment lines ) . The compiler does not do any validation
+and comment lines). The compiler does not do any validation
of the code within the _asm ... _endasm; keyword pair.
Inline assembler code cannot reference any C-Labels however
in inline assembly. The same goes the other way, ie. labels
defines in inline assembly CANNOT be accessed by C statements.
-3.12 int(16 bit) and long (32 bit ) Support
+3.14 int(16 bit) and long (32 bit ) Support
For signed & unsigned int (16 bit) and long (32 bit) variables,
division, multiplication and modulus operations are implemented
source program will have to be compiled with --int-long-rent
option.
-3.13 Floating Point Support
+3.15 Floating Point Support
SDCC supports IEEE (single precision 4bytes) floating point
numbers.The floating point support routines are derived
which case the floating point routines mentioned above will
need to recompiled with the --model-Large option)
-3.14 MCS51 Memory Models
+3.16 MCS51 Memory Models
SDCC allows two memory models for MCS51 code, small and large.
Modules compiled with different memory models should never
model, it is therefore strongly recommdended that the small
model be used unless absolutely required.
-3.15 Flat 24 bit Addressing Model
+3.17 Flat 24 bit Addressing Model
This option generates code for the 24 bit contiguous addressing
mode of the Dallas DS80C390 part. In this mode, up to four
passed to the linker by using the option -Wl-r on the sdcc
command line.
-3.16 Defines Created by the Compiler
+3.18 Defines Created by the Compiler
-The compiler creates the following #defines .
+The compiler creates the following #defines.
* SDCC - this Symbol is always defined.
}
Note: the dead stores created by this copy propagation will
-be eliminated by dead-code elimination .
+be eliminated by dead-code elimination.
4.1.4 Loop Optimizations
of the loop. Because of this preference of the register
allocator , loop induction optimization causes an increase
in register pressure, which may cause unwanted spilling
-of other temporary variables into the stack / data space
-. The compiler will generate a warning message when it is
+of other temporary variables into the stack / data space.
+The compiler will generate a warning message when it is
forced to allocate extra space either on the stack or data
space. If this extra space allocation is undesirable then
induction optimization can be eliminated either for the
Note djnz instruction can be used for 8-bit values ONLY,
therefore it is advantageous to declare loop control symbols
-as either 'char' or 'short', ofcourse this may not be possible
-on all situations.
+as either 'char', ofcourse this may not be possible on all
+situations.
4.1.6 Algebraic Simplifications
then both the switch statements will be implemented using
jump-tables whereas the unmodified switch statement will
-not be .
+not be.
4.1.8 Bit-shifting Operations.
Bit shifting is one of the most frequently used operation
-in embedded programming . SDCC tries to implement bit-shift
+in embedded programming. SDCC tries to implement bit-shift
operations in the most efficient way possible.
eg.
-unsigned short i;
+unsigned char i;
...
i>>= 4;
mov _i,a
SDCC uses pattern matching on the parse tree to determine
-this operation .Variations of this case will also be recognized
+this operation.Variations of this case will also be recognized
as bit-rotation i.e i = ((i >> 7) | (i << 1)); /* left-bit
rotation */
4.1.10 Highest Order Bit
It is frequently required to obtain the highest order bit
-of an integral type (int,long,short or char types). SDCC
+of an integral type (long, int, short or char types). SDCC
recognizes the following expression to yield the highest
order bit and generates optimized code for it.
66 mov
_foo_hob_1_1,a
-Variations of this case however will NOT be recognized .
-It is a standard C expression , so I heartily recommend
-this be the only way to get the highest order bit, (it is
-portable). Of course it will be recognized even if it is
-embedded in other expressions.
+Variations of this case however will NOT be recognized. It
+is a standard C expression , so I heartily recommend this
+be the only way to get the highest order bit, (it is portable).
+Of course it will be recognized even if it is embedded in
+other expressions.
eg.
4.1.11 Peep-hole Optimizer
The compiler uses a rule based , pattern matching and re-writing
-mechanism for peep-hole optimization . It is inspired by
+mechanism for peep-hole optimization. It is inspired by
'copt' a peep-hole optimizer by Christopher W. Fraser (cwfraser@microsoft.com).
A default set of rules are compiled into the compiler, additional
rules may be added with the --peep-file <filename> option.
SDCC supports the following #pragma directives. This directives
are applicable only at a function level.
-* SAVE - this will save all the current options .
+* SAVE - this will save all the current options.
* RESTORE - will restore the saved options from the last
save. Note that SAVES & RESTOREs cannot be nested. SDCC
* NOGCSE - will stop global subexpression elimination.
-* NOINDUCTION - will stop loop induction optimizations .
+* NOINDUCTION - will stop loop induction optimizations.
* NOJTBOUND - will not generate code for boundary value checking
, when switch statements are turned into jump-tables.
format output type argument-type
%d decimal
- int
+ short/int
%ld decimal long
-%hd decimal short/char
+%hd decimal char
-%x hexadecimal int
+%x hexadecimal short/int
%lx hexadecimal long
-%hx hexadecimal short/char
+%hx hexadecimal char
-%o octal int
+%o octal short/int
%lo octal long
-%ho octal short/char
+%ho octal char
-%c character char/short
+%c character char
%s character _generic
pointer
The routine is very stack intesive , --stack-after-data parameter
should be used when using this routine, the routine also
-takes about 1K of code space .It also expects an external
+takes about 1K of code space. It also expects an external
function named putchar(char ) to be present (this can be
changed). When using the %s format the string / pointer
should be cast to a generic pointer. eg.
S. Obukhov (dso@usa.net). These routines are interrupt
driven with a 256 byte circular buffer, they also expect
external ram to be present. Please see documentation in
- file SDCCDIR/sdcc51lib/serial.c . Note the header file
+ file SDCCDIR/sdcc51lib/serial.c. Note the header file
"serial.h" MUST be included in the file containing
the 'main' function.
* reg51.h - contains register definitions for a standard
8051
-* reg552.h - contains register definitions for 80C552.
-
* float.h - contains min, max and other floating point related
stuff.
In the following example the function cfunc calls an assembler
routine asm_func, which takes two parameters.
-extern int asm_func( unsigned short, unsigned short);
+extern int asm_func( unsigned char, unsigned char);
-int c_func (unsigned short i, unsigned short j)
+int c_func (unsigned char i, unsigned char j)
{
return asm_func(i,j);
}
i.e. after the call the left most parameter will be on the
top of the stack. Here is an example.
-extern int asm_func( unsigned short, unsigned short);
+extern int asm_func( unsigned char, unsigned char);
-int c_func (unsigned short i, unsigned short j) reentrant
-
+int c_func (unsigned char i, unsigned char j) reentrant
{
return asm_func(i,j);
}
code, _bp is the stack frame pointer and is used to compute
the offset into the stack for parameters and local variables.
-4.6 With --noregparms Option
-
-When the source is compiled with --noregparms option , space
-is allocated for each of the parameters passed to a routine.
-
-4.6.1 Assembler Routine Non-reentrant
-
-In the following example the function cfunc calls an assembler
-routine asm_func, which takes two parameters.
-
-extern int asm_func( unsigned short, unsigned short);
-
-
-int c_func (unsigned short i, unsigned short j)
-{
- return asm_func(i,j);
-}
-int main()
-{
- return c_func(10,9);
-}
-
-The corresponding assembler function is:-
-
- .globl _asm_func_PARM_1
- .globl _asm_func_PARM_2
- .globl _asm_func
- .area OSEG
-_asm_func_PARM_1:
-.ds 1
-_asm_func_PARM_2:
-.ds 1
- .area CSEG
-_asm_func:
- mov
-a,_asm_func_PARM_1
- add
-a,_asm_func_PARM_2
- mov
-dpl,a
- mov
-dpl,#0x00
- ret
-
-Note here that the return values are placed in 'dpl' - One
-byte return value, 'dpl' LSB & 'dph' MSB for two byte values.
-'dpl', 'dph' and 'b' for three byte values (generic pointers)
-and 'dpl','dph','b' & 'acc' for four byte values.
-
-The parameter naming convention is _<function_name>_PARM_<n>,
-where n is the parameter number starting from 1, and counting
-from the left. i.e. the left-most parameter name will be
-_<function_name>_PARM_1.
-
-Assemble the assembler routine with the following command.
-
-asx8051 -losg asmfunc.asm
-
-Then compile and link the assembler routine to the C source
-file with the following command,
-
-sdcc cfunc.c asmfunc.rel
-
-4.6.2 Assembler Routine(reentrant)
-
-In this case the parameters will be passed on the stack ,
-the parameters are pushed from right to left i.e. after
-the call the left most parameter will be on the top of the
-stack. Here is an example.
-
-extern int asm_func( unsigned short, unsigned short);
-
-
-
-int c_func (unsigned short i, unsigned short j) reentrant
-
-{
- return asm_func(i,j);
-}
-int main()
-{
- return c_func(10,9);
-}
-
-The corresponding assembler routine is.
-
- .globl _asm_func
-_asm_func:
- push _bp
- mov _bp,sp
- mov a,_bp
- clr c
- add a,#0xfd
- mov r0,a
- mov a,_bp
- clr c
- add a,#0xfc
- mov r1,a
- mov a,@r0
- add a,@r1
- mov dpl,a
- mov dph,#0x00
- mov sp,_bp
- pop _bp
- ret
-
-The compiling and linking procedure remains the same, however
-note the extra entry & exit linkage required for the assembler
-code, _bp is the stack frame pointer and is used to compute
-the offset into the stack for parameters and local variables.
-
-4.7 External Stack
+4.6 External Stack
The external stack is located at the start of the external
ram segment , and is 256 bytes in size. When --xstack option
the External Stack option, this port MAY NOT be used by
the application program.
-4.8 ANSI-Compliance
+4.7 ANSI-Compliance
Deviations from the compliancy.
(*foo)();/* ansi standard allows calls to be made like
'foo()' */
-4.9 Cyclomatic Complexity
+4.8 Cyclomatic Complexity
Cyclomatic complexity of a function is defined as the number
of independent paths the program can take during execution
of the function. This is an important number since it defines
the number test cases you have to generate to validate the
-function . The accepted industry standard for complexity
+function. The accepted industry standard for complexity
number is 10, if the cyclomatic complexity reported by SDCC
exceeds 10 you should think about simplification of the
function logic.
* Use the smallest data type to represent your data-value.
If it is known in advance that the value is going to be
- less than 256 then use a 'short' or 'char' instead of
- an 'int'.
+ less than 256 then use a 'char' instead of a 'short' or
+ 'int'.
* Use unsigned when it is known in advance that the value
is not going to be negative. This helps especially if
to registers, and for how long.
5. Phase five is register allocation. There are two parts
- to this process .
+ to this process.
(a) The first part I call 'register packing' (for lack of
- a better term) . In this case several MCU specific expression
+ a better term). In this case several MCU specific expression
folding is done to reduce register pressure.
(b) The second part is more MCU independent and deals with
debug information is to be generated. The complier generates
a .cdb file for each of these files. The linker updates
the .cdb file with the address information. This .cdb is
-used by the debugger .
+used by the debugger.
7.2 How the Debugger Works
by the linker. It uses the SIMULATOR (Daniel's S51) to execute
the program, the program execution is controlled by the
debugger. When a command is issued for the debugger, it
-translates it into appropriate commands for the simulator .
+translates it into appropriate commands for the simulator.
7.3 Starting the Debugger
& ihx files. The items in the directory list must be separated
by ':' , e.g. if the source files can be in the directories
/home/src1 and /home/src2, the --directory option should
- be --directory=/home/src1:/home/src2 . Note there can
- be no spaces in the option.
+ be --directory=/home/src1:/home/src2. Note there can be
+ no spaces in the option.
* -cd <directory> - change to the <directory>.
REQUIRED), the files can also be loaded dynamically while
XEmacs is running, set the environment variable 'EMACSLOADPATH'
to the installation bin directory [$(prefix)/bin], then
-enter the following command ESC-x load-file sdcdbsrc . To
+enter the following command ESC-x load-file sdcdbsrc. To
start the interface enter the following command ESC-x sdcdbsrc
, you will prompted to enter the file name to be debugged.