ARM Technical Support Knowledge Articles


Applies to: C51 C Compiler


Information in this article applies to:


I have created a program and I'm using bit variables. However, when I link my program, I notice that the linker leaves a huge (15 byte) gap between my register banks and the bit area.

            DATA    0008H     0005H     UNIT         ?DT?RJUDSIO
            IDATA   000DH     0004H     UNIT         ?ID?DATAFLASH
                    0011H     000FH                  *** GAP ***
            BIT     0020H.0   0000H.3   UNIT         ?BI?DATALOG
            BIT     0020H.3   0000H.1   UNIT         ?BI?DATAFLASH
            BIT     0020H.4   0000H.1   UNIT         ?BI?RJUDSPI
                    0020H.5   0000H.3                *** GAP ***

What would cause that?


  1. The compiler ALWAYS uses 8 bytes of data starting at 0x00. This is used for the registers R0-R7. If you use multiple register banks, more memory is used. From this MAP listing, only one register bank is used.
  2. There are 3 bit variables declared. The bit memory on the 8051 starts at 0x20. It cannot start lower than that because addresses lower than 0x20 are not bit-addressable and, therefore, can't be used for bit variables.
  3. The space between 0x08 and 0x20 is 24 bytes. So, the linker trys to use this space for DATA or IDATA segments. In this case, all it could fit was the IDATA variables from DATAFLASH. Other DATA and IDATA segments were larger than 15 bytes. So, the linker was not able to use the remaining space and left a gap.

To avoid the GAP in this situation, change your BIT variables to unsigned char. They will take up more space (1 byte as opposed to a bit), but you won't have a 15-byte gap that is wasted. And, you'll gain 12 more bytes of data space.

Another method you may use is to move the BIT area a few bytes higher in memory. If you have a DATA or IDATA segment that is 17 bytes long, you could start the BIT area at 022h. This would leave 17 unused bytes between ?DI?DATAFLASH and the BIT area. And, a 17-byte segment could fit there. Be very careful doing this since changes to your program will probably change segment sizes.

Sometimes you may be required to use a linker directive to close or minimize the stack. When BL51 is used, this can be done with the PRECEED directive. You can specify some data segments that are big enough to fill the gap between register banks and the bit addressable space. These segments preceed the bit space (Refer to A51 User's Guide, PRECEED for more info). When LX51 is used, the SEGMENTS directive can be used for doing effectively the same thing. Just specify the data segments with the address after the bit space.

Article last edited on: 2005-07-09 10:54:21

Rate this article

Disagree? Move your mouse over the bar and click

Did you find this article helpful? Yes No

How can we improve this article?

Link to this article
Copyright © 2011 ARM Limited. All rights reserved. External (Open), Non-Confidential