

*********************
Placing code and data
*********************

When compiling for modern computers, code and data placement often requires
minimal attention, as tools handle it effectively for same-machine targets.

Cross-compilation is more complex, requiring knowledge of the target
system. Embedded systems are even more challenging, with widely varying
memory systems necessitating precise control over code and data placement.

Effective embedded system tools provide control over code and data
placement. This is achieved using building blocks that offer placement
flexibility and control. The compiler assists by providing abstractions
through type qualifiers, initializers, and runtime model settings, which
simplify configuring the memory system.

.. index:: section

Sections
========

A *section* is a unit of code or data. The compiler will place code
and data into different sections which are saved as separate sections
in the object file.

The compiler places data objects and functions into suitable sections
following specific rules. For data objects, it considers if the object is
``const``, its address space, and explicit initializers.

.. index:: code; section, zdata; section, data; section, cdata; section
.. index:: zzpage; section, zpage; section, switch; section
.. index:: idata; section
.. index:: data_init_table; section

.. index:: section; code, section; zdata, section; data, section; cdata
.. index:: section; zzpage, section; zpage, section; switch
.. index:: section; idata
.. index:: section; data_init_table

.. table:: Sections
 :widths: 2 1 1 5
 :column-dividers: none single single single none
 :column-alignment: left left left left

 +----------------------+------------+------------------+----------------------------+
 |Section name          |Type        |Memory kind       |Description                 |
 +======================+============+==================+============================+
 | ``code``             |text        |ROM               |Executable code             |
 +----------------------+------------+------------------+----------------------------+
 | ``zdata``            |bss         |RAM               |Zero-initialized (bss) data |
 +----------------------+------------+------------------+----------------------------+
 | ``data``             |data        |RAM               |Initialized data            |
 +----------------------+------------+------------------+----------------------------+
 | ``cdata``            |rodata      |ROM               |Constant data               |
 +----------------------+------------+------------------+----------------------------+
 | ``zzpage``           |bss         |RAM               |Zero-initialized (bss) zero |
 |                      |            |                  |page data                   |
 +----------------------+------------+------------------+----------------------------+
 | ``zpage``            |data        |RAM               |Initialized zero page data  |
 +----------------------+------------+------------------+----------------------------+
 | ``switch``           |rodata      |ROM               |Switch tables               |
 +----------------------+------------+------------------+----------------------------+
 | ``izpage``           |rodata      |ROM               |Data initializers for       |
 |                      |            |                  |``zpage`` section           |
 +----------------------+------------+------------------+----------------------------+
 | ``idata``            |rodata      |ROM               |Data initializers for       |
 |                      |            |                  |``data`` section            |
 +----------------------+------------+------------------+----------------------------+
 | ``data_init_table``  |rodata      |ROM               |Data initializer table      |
 +----------------------+------------+------------------+----------------------------+
 | ``registers``        |noinit      |RAM               |Pseudo registers in zero    |
 |                      |            |                  |page                        |
 +----------------------+------------+------------------+----------------------------+
 | ``reset``            |text        |ROM               |Reset vector, when used     |
 +----------------------+------------+------------------+----------------------------+
 | ``heap``             |noinit      |RAM               |Heap memory, for            |
 |                      |            |                  |``malloc()``                |
 +----------------------+------------+------------------+----------------------------+
 | ``stack``            |noinit      |RAM               |CPU stack, always in page   |
 |                      |            |                  |1 on the 6502               |
 +----------------------+------------+------------------+----------------------------+
 | ``cstack``           |noinit      |RAM               |C stack, simulated stack,   |
 |                      |            |                  |anywhere in memory          |
 +----------------------+------------+------------------+----------------------------+
 | ``zpsave``           |noinit      |RAM               |Commodore targets, save     |
 |                      |            |                  |area for ``registers``      |
 |                      |            |                  |section                     |
 +----------------------+------------+------------------+----------------------------+
 | ``zfar``             |bss         |RAM               |Zero-initialized (bss)      |
 |                      |            |                  |far data, MEGA65 only       |
 +----------------------+------------+------------------+----------------------------+
 | ``far``              |data        |RAM               |Initialized far data,       |
 |                      |            |                  |and MEGA65 only             |
 +----------------------+------------+------------------+----------------------------+
 | ``cfar``             |rodata      |ROM               |Constant far data,          |
 |                      |            |                  |MEGA65 only                 |
 +----------------------+------------+------------------+----------------------------+
 | ``ifar``             |rodata      |ROM               |Data initializers for       |
 |                      |            |                  |``far`` section,            |
 |                      |            |                  |MEGA65 only                 |
 +----------------------+------------+------------------+----------------------------+
 | ``zhuge``            |bss         |RAM               |Zero-initialized (bss)      |
 |                      |            |                  |huge data, MEGA65 only      |
 +----------------------+------------+------------------+----------------------------+
 | ``huge``             |data        |RAM               |Initialized huge data,      |
 |                      |            |                  |MEGA65 only                 |
 +----------------------+------------+------------------+----------------------------+
 | ``chuge``            |rodata      |ROM               |Constant huge data,         |
 |                      |            |                  |MEGA65 only                 |
 +----------------------+------------+------------------+----------------------------+
 | ``ihuge``            |rodata      |ROM               |Data initializers for       |
 |                      |            |                  |``huge`` section,           |
 |                      |            |                  |MEGA65 only                 |
 +----------------------+------------+------------------+----------------------------+

The sections ``izpage``, ``idata``, ``ifar``, ``ihuge``, and ``data_init_table``
in the table above are linker generated.

.. note::

   It is assumed that no ROM exists in the zero page. Consequently,
   constants placed in the zero page are placed in ``zpage`` (the normal
   RAM initialized zero page section), and the ``const`` attribute only
   affects the object type.

.. note::

   The table assigns sections to ROM and RAM for ROM-based applications
   that start on power-up. For hosted systems loading from storage to
   RAM, this distinction is not applicable. Always consider ROM-marked
   sections as read-only.

Section types are derived from the UNIX world; see :ref:`sectionkinds`
in the assembler reference for details.

.. note::

   When generating a ROM-executable application, the linker separates an
   initialized data section into two. Initializers go into a new ``i``-prefixed
   section (placed in ROM); the data section is placed in RAM. The C runtime
   startup module copies initializers from ROM to RAM before giving control to
   the ``main()`` function.


Linking process
----------------

The linker reads object files with sections and a placement rules file.
This file describes available memory areas and their permitted sections,
optionally with additional placement constraints.

Memories containing actual value bits (program code or initialized data)
are emitted in the executable.

An executable can serve as input for ROM or FLASH programmers, be loaded by
the target machine, or be used by a debugger that connects to or simulates
the target. Various executable formats are available to suit different
execution environments.

.. note::

   Although code and data are entirely separated into different sections,
   placing these sections together in the same memory may be desirable.
   This can be achieved at the link stage.

.. index:: linker rules, section; placement
.. index:: placement control

Placing sections in memory
--------------------------

The linker rules file uses file extension ``.scm``, which is actually
a source file in the Scheme language. However, you do not need to
learn Scheme in order to use it, as it just a simple description of
available memories and their associated properties. Sections are then
bound to the memories. You can also define the size of the stack and
heap in this file.

A simple example of such linker rules file is:

.. literalinclude:: example/simple-linker-rules.scm
   :language: scheme

The Scheme interpreter evaluates the rules file, which defines a single
global ``memories`` object. This object lists ``memory`` and block
objects. Sections can be bound to memories either by specifying the memory
type or by listing the sections within each memory.

The example simplifies memory system description. The linker deduces where
compiler and linker-generated sections are placed; this requires specifying
the memory type. To prevent automatic section placement in a memory, omit
its type specification.

.. note::

   You can specify a memory type and manually place custom sections.
   This is useful for sections requiring specific placement.

.. note::

   Since the linker rules file is a Scheme program, it can theoretically
   construct the ``memories`` object via functions or macros. After evaluation,
   the Scheme interpreter is expected to leave a ``memories`` object in its
   global environment. However, a simple file like the example is usually
   sufficient.

.. index:: initialization; of data, data initialization
.. index:: heap; initialization, file streams; initialization

Data initialization
===================

A startup routine is performed before the ``main()`` function is called. This
startup routine takes care of preparing the execution environment for the C
program by initializing the stack pointer, initialize global variables
and prepare system resources such as file streams and the heap, if
used by the application.

Static data
-----------

Static data that needs to be initialized comes in two forms, zero
initialized and those that have non-zero initializers. Zero
initialization is done by filling such memory ranges with zero.
Explicit initialization is done by copying an initializer section in
ROM to its corresponding RAM area.

This process is table driven using a section named ``data_init_table``
which should be placed in the same memory as the ``cdata`` section, which
holds constants.

.. note::

   In a hosted environment, the linker provides the ``--hosted`` command-line
   option. This assumes the program image loads directly into RAM from
   external media. Variable initialization is done in-place via the
   load action; therefore, separate initializers are not required.

   The ``--target`` option also has the effect of enabling running in a hosted environment.

.. index:: stack; usage

Stack
=====

The 6502 has a small 256-byte built-in stack for saving return
addresses and registers. C variables are managed on a separate stack in
the larger default memory, with arbitrary size up to 64K. Its stack pointer
is a pseudo-register named ``_Vsp`` in the zero page.

These stacks help track the current execution state and enable the
implementation of reentrant and recursive functions.

.. index:: stack; size considerations

Stack size considerations
-------------------------

The stack sizes are defined in the linker rules file.
The stack size should be set low as possible, but not any lower.
If given too much space you are wasting RAM space not
being used for anything. However, if set too small it will cause
corruption of other data.

Exact stack use can be hard to predict and it is better to err on the
side of some safety. Also during development of your application you
may want to use a bit oversized stack if possible, to allow you to focus
on other issues. In the end, you are most likely constrained by some
fixed amount of RAM and need to balance how much you can use for the
stack with the optional heap and statically allocated data.
