Hi all,

I have recently developed a technique for the STM8 platform to have assembly code functions automatically placed in RAM by SDCC's bootstrap process and have this RAM-resident code be callable from C code. I thought I would share this technique on the mailing list in case anyone else finds it useful.

It takes advantage of how the SDCC bootstrap code (which is generated in the 'main' module, jumped to upon reset) copies data from flash to RAM in order to initialise the values of global variables. What that does is simply copy a defined number of bytes from the INITIALIZER section (in flash) to the INITIALIZED section (in RAM). We can co-opt this process to have executable code copied as well.

Put briefly, what we do is tell the assembler to put the code implementing our functions in the INITIALIZER section (as opposed to CODE section), but not export those particular labels. Instead, we put the exported labels (i.e. the function call entry points) in the INITIALIZED section and tell the assembler to reserve an amount of space there for each equivalent to the size of the code of the corresponding implementing function. This reserved space is what the bootstrap process will copy into.

Let me illustrate the technique by way of example. Say we are writing two assembly code functions that are exported to our C code (using a header file) with the following function declarations:

extern unsigned char add_10_func(unsigned char val);
extern unsigned char sub_10_func(unsigned char val);

If we want them to be RAM-resident, our assembly code file would be as follows:

.module foo
.globl _add_10_func
.globl _sub_10_func

; ------------------------------------------------------------------------------

; Must define default segment ordering for linker, in case this is linked first.
.area DATA
.area INITIALIZED
.area SSEG
.area DABS (ABS)
.area HOME
.area GSINIT
.area GSFINAL
.area CONST
.area INITIALIZER
.area CODE

; ------------------------------------------------------------------------------

.area INITIALIZER

; At startup, the __sdcc_init_data() procedure (in main module) will copy data ; from INITIALIZER to INITIALIZED. We place the actual function code here in the
; former, but will be executed from the copy in the latter at run-time.

add_10_func:
    ld a, (3, sp)
    add a, #10
    ret

ADD_10_FUNC_CODE_SIZE = (. - add_10_func)

sub_10_func:
    ld a, (3, sp)
    sub a, #10
    ret

SUB_10_FUNC_CODE_SIZE = (. - sub_10_func)

; ------------------------------------------------------------------------------

.area INITIALIZED

; Here we reserve space for the RAM-resident function code to live. These
; locations are also the callable labels for the exported function names.
; IMPORTANT: these must be in the same order as the actual function code!

_add_10_func:
    .ds ADD_10_FUNC_CODE_SIZE
_sub_10_func:
    .ds SUB_10_FUNC_CODE_SIZE

Some notes:

- A function's code size is calculated by taking the position of the start of the function (i.e. its label) and subtracting that from the current position (using '.' keyword) after the function. The resultant value is assigned to a symbol for use later with a '.ds' assembler directive.

- The exported function labels in the INITIALIZED section *must* be in the same order as the function implementation code in the INITIALIZER section.

- The bunch of '.area' statements listing every section name SDCC utilises is there in case the object file is linked first, before any C code. It seems SDCC determines the order of sections to declare to the linker by the order they are first encountered. Without this, things went wrong if the assembly code's .rel file was given to the linker first.

- The assembly code should be built with the command 'sdasstm8 -ff -w -l -p -o foo.rel foo.s' and the output object file linked as per normal.

If anyone has an questions, feel free to ask. :)

Regards,
Basil Hussain

P.S. In case you're wondering why I needed this, it's because I was experimenting with self-modifying assembly code, which of course needs to be in RAM in order for it to be modifiable.


_______________________________________________
Sdcc-user mailing list
Sdcc-user@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sdcc-user

Reply via email to