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

ROM() Directive Effect on Code Generation

The ROM(small/compact/large) directive, selected by the "Code Rom Size" option in the uVision Target dialog, tells the compiler to generate ACALL / AJMP instructions inside functions (compact) or for the whole program (small).

There is also a "linker code packing" checkbox on the C51 optimization options. This optimization allows the linker to rearrange code to use the short instructions where possible, replacing LCALL / LJMP with the Ax versions.

Is the ROM directive thus redundant? Or is there some additional benefit to the code generated with the ROM(compact) memory model selection compared to ROM(large)?

(I'm contemplating switching from the large model to small. I have most of my variables explicitly assigned to a memory space, and make heavy use of overlaid data for auto variables (the "stack"). This noticably improves code size over the default to xdata. However, it seems that parameters that spill out of registers, and compiler-generated temporaries will still appear in xdata, with all the painful access that implies. So I was hoping a switch to the small model would move these locations into internal RAM as well, and buy me a little more code space. Hopefully it doesn't blow my "stack" size altogether.)

  • ROM is a Compiler directive, but Linker Code Packing is performed by the Linker - and, I think, only by LX51 not by BL51.

    Since not all of Keil's 8051 toolsets include LX51, the ROM directive is certainly not redundant from Keil's perspective.
    http://www.keil.com/c51/

    If you do have LX51, the Linker Code Packing can make debugging a real nightmare - since the executable code can bear very little resemblance to your 'C' source lines!
    So, if you can get what you need using just the ROM directive, I'd say that would still be useful.

    I guess it might also give better results if you can generate short instructions in the first place, rather than have the Linker trying to figure them out after the event?
    Dunno about that one...

  • "it seems that parameters that spill out of registers, and compiler-generated temporaries will still appear in xdata"

    The Memory Model setting controls this; it is independant of the Code ROM Size setting.

    You should use the SMALL Memory Model, and explicitly declare those variables that need to go into XDATA.

  • Is the ROM directive thus redundant? Or is there some additional benefit to the code generated with the ROM(compact) memory model selection compared to ROM(large)?

    No. The ROM directive is not redundant. However, if you allows the LX51 linker to substitute shorter JMP and CALL instructions, its use it unimportant (since the linker moves things around to maximize AJMPs and ACALLs.

    ROM is useful in cases where you don't want this level of linker optimization or in cases where you don't have the LX51 linker.

    The real difference is that the ROM directive forces you to maintain the size of functions or modules while using the linker does not.

    Jon

  • "The real difference is that the ROM directive forces you to maintain the size of functions or modules"

    Does the compiler warn you if your functions/modules get too big?

  • I believe you get a segment too large error but I haven't tested it.

    Jon

  • Thanks for the clarifications.