5

I have tried searching for an answer to this but can not find a definitive reason.

I am trying to optimise some 8051 C code to reduce code space. I made the following change..

xdata unsigned char a, b;

to

data unsigned char a, b;

... and saw my Code size reduce by 39Bytes(feels like christmas).

From: Program Size: data=9.0 ...code=10509

to: Program Size: data=11.0 ... code=10468

Question: Why has the codespace reduced by so much for such a minor change?

Ben Jackson
  • 90,079
  • 9
  • 98
  • 150
user968722
  • 59
  • 3
  • I am aware that using data saves instructions by not having to use the DPTR to access memory. But 39Bytes is more than expected. – user968722 Jan 31 '14 at 11:31
  • it depends on how much you use that variable. The more it reloads the value, the larger the code is – phuclv Jan 31 '14 at 12:15
  • That looks a lot like assembler and not C... – RedX Jan 31 '14 at 12:36
  • @RedX, why do you think this looks like assembler? data, xdata are Cx51 keyboards, U8 is a "unsigned char" #define and there is a semicolon. – user968722 Jan 31 '14 at 14:07
  • You can use the preprocessor also on non C files. Assembler files for example. Take a look [here](http://en.wikipedia.org/wiki/X86_assembly_language) for what assembly looks like and [here](http://en.wikipedia.org/wiki/C_%28programming_language%29) for what C language looks like. – RedX Jan 31 '14 at 14:43
  • I am still a little confused RedX. I already know what assembly and C syntax looks like. Maybe I should have written "xdata unsigned char a, b" to be clearer? But apart from that, it is pretty much a standard C declaration in Cx51 [link](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.kui0002a/c51_le_xdata.htm). – user968722 Jan 31 '14 at 15:08

1 Answers1

4

It depends on how you're using (and how many times you're using) those variables. xdata requires 16 bit addressing, and that takes more space. Just as an example, loading into the accumulator a value at a fixed address takes twice as much code space with xdata as it does with data:

Load accumulator with value at 30h (data):

MOV A, 30h       ; 2 bytes

Load accumulator with value at 1230h (xdata):

MOV DPTR, #1230h ; 3 bytes
MOVX A, @DPTR    ; 1 byte

Copying from data to data takes three bytes (MOV direct, direct), copying from xdata to xdata could take eight bytes (MOV DPTR, #addr1; MOVX; MOV DPTR #addr2; MOVX). If you are accessing these variables many times and the compiler couldn't optimize their use with registers, it can add up quickly.

Phil Wetzel
  • 135
  • 4
  • Thanks. This may explain why the compiler doesn't not always optimise the code when i use data instead of xdata. So i guess it depends on how much the compiler has optimised already(Keil Level 9 is pretty efficient) and how much the variable is accessed. – user968722 Jan 31 '14 at 14:03
  • 1
    Again, it really depends on what your algorithm is doing with those variables. You run out of registers quick, and after that there's not much the compiler can do to make a memory access faster. We use Keil as well, and we see big jumps like this all the time. Always use the small model and move less-used or big variables to xdata as necessary to make space. You'll end up with much faster and more compact code. – Phil Wetzel Jan 31 '14 at 14:30
  • Thank you. Yes I have seen random jumps a lot with Keil. I wish i knew how to beat the compiler every time. But it seems too random. – user968722 Jan 31 '14 at 15:16