Re: SDCC and internal RAM layout for 8051



Johnie wrote:
Hello

I'm writing application for AT89S52 microcontroller and using SDCC to
compile. Now I have come to a point where I can't declare anymore
global variables or else ASLink will complain about being "unable to
get 21 consecutive bytes in internal RAM for area DSEG". Here's the
memory layout from a compilation that worked:

Internal RAM layout:
0 1 2 3 4 5 6 7 8 9 A B C D E F
0x00:|0|0|0|0|0|0|0|0|b|b|c|c|c|c|c|c|
0x10:|c|d|Q|Q|Q|Q|Q|Q|Q|Q|Q|Q|Q| | | |
0x20:|B|B|T|a|a|a|a|a|a|a|a|a|a|a|a|a|
0x30:|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
0x40:|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
0x50:|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|a|
0x60:|a|a|a|a|a|a|a|a|a|a|a|e|e|e|e|e|
0x70:|e|e|e|e|e|e|e|e|e|e|e|e|e|e|e|e|
0x80:|I|I|I|I|I|I|S|S|S|S|S|S|S|S|S|S|
0x90:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0xa0:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0xb0:|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|S|
0xc0:|S|S|S|S|S| | | | | | | | | | | |
0xd0:| | | | | | | | | | | | | | | | |
0xe0:| | | | | | | | | | | | | | | | |
0xf0:| | | | | | | | | | | | | | | | |
0-3:Reg Banks, T:Bit regs, a-z:Data, B:Bits, Q:Overlay, I:iData,
S:Stack, A:Absolute

Stack starts at: 0x86 (sp set to 0x85) with 122 bytes available.

Now, if I declare one more global char variable, I get this dreaded
error although there seems to be plenty of free space at the end
(stack size is set to 63 to make more room for DSEG). Why?

The stack can use iData, but Data variables cannot extend past address 0x7F. Directly addressed locations 0x80 .. 0xFF are the Special Function Registers, not Data.

Is it possible to move the I-segment so that it starts at
say 0xA0 and S-segment (stack) at 0xA7?

No. The start of I = iData at 0x80 is fixed by the processor architecture. The directly addressable Data memory ends at 0x7F. You can make the stack start where you like (in Data or iData), but SDCC should place it automatically, see below.

To use the iData area for C variables, you must declare selected variables with the "__idata" storage class keyword, for example:

__idata unsigned char k;

That will make variable "k" use the iData space (0x80 .. 0xFF, with indirect addressing) instead of the Data space (which is the default in the "small" memory model). Access to "k" will be slower and take more code than if "k" were in Data, but if you have more variables than can fit in Data, you must place some of them in iData (or external data memory, but I assume your system does not have that).

I tried these command line options:
--stack-size 63 --stack-loc 0xA7 --no-pack-iram --data-loc 0x23
--idata-loc 0xA0

SDCC should place the stack automatically after the last iData variable. As long as you can fit your variables in Data (default, in the "small" memory model) plus iData (manually, with the __idata keyword), with enough iData space left over for the stack, you should not need any of those options.

HTH,

--
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
. @ .
.



Relevant Pages

  • Re: Difference between the stack and the heap?
    ... If you just declare a variable or array like this: ... the system uses a stack. ... char * pc = malloc; ... then the memory is allocated on the heap, ...
    (comp.lang.c)
  • Re: ReadFile() fails on hardware RAID disk.How to detect that disk
    ... It's a common mistake to declare handle in stack, ... and checked the pointer as well as memory in memory watch....nothing was ...
    (microsoft.public.win32.programmer.kernel)
  • Re: Memory Analysis confuse me
    ... memory size are growing to 100MB. ... If I declare a huge parameter in the stack, but do not initialze, ...
    (comp.os.linux.misc)
  • Re: reset memory size
    ... Tim Ward wrote: ... >>size of memory to run, and when I declare the objects to the size I need ... > Allocate on the heap rather than the stack? ...
    (microsoft.public.vc.mfc)
  • Re: xdata/idata/data differences
    ... BYTE idata temp; ... yourself with the processor memory architecture. ... series MCU which is in fact a 8051 type processor. ...
    (comp.arch.embedded)