SDCC and internal RAM layout for 8051

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? Is it possible to move the I-segment so that it starts at say 0xA0 and S-segment (stack) at 0xA7?

I tried these command line options:

--stack-size 63 --stack-loc 0xA7 --no-pack-iram --data-loc 0x23

--idata-loc 0xA0

But now it gives me another error message: "Insufficient space in data memory. 21 bytes short."

I thought that there would be 0xA0-0x23 = 125 bytes long DSEG when using those command line options, but it doesn't seem to be the case?

TIA.

Reply to
Johnie
Loading thread data ...

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.

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).

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
 Click to see the full signature
Reply to
Niklas Holsti

Thank you for your reply. I read about 0x80 and up being only indirectly-addressable right after posting my earlier message. __idata keyword seems to be solution to my problem... little performance loss accessing idata shouldn't be a problem.

Reply to
Johnie

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.