This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Problem writing DWORD xdata

I just noticed this recently... whenever I have a xdata DWORD - 32 bits - and I try to set it to a constant value (or any value I think), the assembly that gets generated seems all messed up for such a simple routine. See below. Writing a WORD (TotalSleepTime.m16.ab) works fine, but writing a DWORD (NextSleepTime), makes a call to some external routine which is excessively long and then has a series of NOPs.

    77:         TotalSleepTime.m16.ab = 0;
C:0x3347    900181   MOV      DPTR,#TotalSleepTime(0x0181)
C:0x334A    F0       MOVX     @DPTR,A
C:0x334B    A3       INC      DPTR
C:0x334C    F0       MOVX     @DPTR,A
    78:         TotalSleepTime.m16.cd = 0;
    79:
C:0x334D    900183   MOV      DPTR,#0x0183
C:0x3350    F0       MOVX     @DPTR,A
C:0x3351    A3       INC      DPTR
C:0x3352    F0       MOVX     @DPTR,A
    80:         NextSleepTime = 1;
C:0x3353    900185   MOV      DPTR,#NextSleepTime(0x0185)
C:0x3356    120FB2   LCALL    C?LSTKXDATA(C:0FB2)
C:0x3359    00       NOP
C:0x335A    00       NOP
C:0x335B    00       NOP
C:0x335C    0122     AJMP     C:3022

I noticed that something like

variable.m32.abcd = 0

would generate screwed up code like this, so I though it may have to do with the union not being accessed correctly, so I tried changing a variable just to a straight up DWORD (NextSleepTime as seen above), but the same thing happens.

Is this behavior normal? I can't follow the undocumented assembly that is called very well, but it definitely seems excessively complicated for a simple command. I just checked on a blank project with

void main(void)
{
   unsigned long xdata test;
   test = 0;
}

Same thing.

Parents
  • I can understand that if I were using 32-bit variables all over my code, using the library routine would probably save a lot of code SIZE while compromising speed, but this is the ONLY place that I ever assign a 32 variable to an immediate value.

    You pretty much answered your own question right there. You presumably asked for size-optimized code, and the tools do what is the most probable to yield the smallest code, in a typical situation. And your counter-example is biased --- 0 is an untypically simple case. Once you generalize that to an arbitrary immediate value to write, code following your pattern would grow from 11 to a whopping 18 bytes, compared to the compiler's 10. Which means the compiler wins as soon as there are about 5 of these operations in the entire program.

    The only insight missing is that there's no way for the compiler to guess that this is going to be the single such operation in the whole program, because the compiler doesn't usually see the whole program. Only the linker sees the whole program, but it doesn't get to decide about micro-scale code generation.

Reply
  • I can understand that if I were using 32-bit variables all over my code, using the library routine would probably save a lot of code SIZE while compromising speed, but this is the ONLY place that I ever assign a 32 variable to an immediate value.

    You pretty much answered your own question right there. You presumably asked for size-optimized code, and the tools do what is the most probable to yield the smallest code, in a typical situation. And your counter-example is biased --- 0 is an untypically simple case. Once you generalize that to an arbitrary immediate value to write, code following your pattern would grow from 11 to a whopping 18 bytes, compared to the compiler's 10. Which means the compiler wins as soon as there are about 5 of these operations in the entire program.

    The only insight missing is that there's no way for the compiler to guess that this is going to be the single such operation in the whole program, because the compiler doesn't usually see the whole program. Only the linker sees the whole program, but it doesn't get to decide about micro-scale code generation.

Children
No data