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

what's the function of "AREGS"and "NOAREGS"

what's the function of "AREGS"and "NOAREGS", can you provide me some sample, so that I could understand them clear. Are them still useful in current updated versions.
In the manual it is said that with "NOAREGS" the function could be called by another functions using different register bank.

#pragma NOAREGS
char add(char i)
{
    return i+10;
}

void main(void) using 1
{
    ch = add(3);
}

whether I enable or disable #pragma NOAREGS
I always get the right result. If with "NOAREGS" the function could be called by another functions using different register bank, then does it also mean that with "AREGS" the function could not be called by another functions using different register bank. I am very confused with "AREGS"and "NOAREGS".

Parents
  • The discussed directives have, as far as I know, the meaning I have explained.
    NOAREGS disables absolute register access, while AREGS enables (but not forces) it.
    When enabled, the compiler decides whether to use it or not in a particular
    situation ("is it advantageous or not?"). It doesn't mean that the addressing method
    unconditionally changes to absolute register accesses in every case.
    See your compiled programs in my previous post. You obtain the same result
    either you use AREGS or NOAREGS, because in both these examples NOAREGS
    option "prevails". There is no reason for absolute register access there.
    That's why it is not used even if AREGS option is selected.


    "But in the manual it is said that with "NOAREGS" one function could be called
    by another functions using different register bank..."


    In my opinion it is confusing (if not even wrong)
    as far as passing parameters or return values in registers are concerned.


    I suppose you mean C51.pdf, page 24 (?):

    "This directive may be used for functions that are called from other
    functions using different register banks."


    or further, on page 124:

    "To make a function insensitive to the current register bank, the function must be
    compiled using the NOAREGS control directive. This would be useful for a
    function that was called from the main program and also from an interrupt
    function that uses a different register bank.
    Note:
    The Cx51 compiler does not and cannot detect a register bank mismatch
    between functions. Therefore, make sure that functions using alternate register
    banks call only other functions that do not assume a default register bank."


    and later, page 128:

    "Functions called from an interrupt procedure must function with the same
    register bank as the interrupt procedure. When the NOAREGS directive is
    not explicitly specified, the compiler may generate absolute register accesses
    using the register bank selected (by the using attribute or by the
    REGISTERBANK control) for that function. Unpredictable results may
    occur when a function assumes a register bank other than the one currently
    selected."


    Once more as to the function register bank in/dependance -
    for instance lets assume 2 functions:

    a) func1() compiled with NOAREGS pragma,
    containing "mov r7,a" instruction in its body,
    the resulting code is 0xFF

    b) func2() compiled with AREGS pragma,
    containing corresponding to the above "mov ar7,a" instruction in its body,
    the resulting codes are 0xF5 0x17 if register bank used at compile time was 2

    if current register bank for both functions at calling time is, say, 1,
    then func1() will always write in R7 of the current register bank
    while func2() will write in absolute address 17H which is probably not the intention

    This is, among others, what they meant "To make a function insensitive
    to the current register bank..."


    In my opinion the RB independence concerns rather the body of the function
    than parameters or return values passed in registers.
    The directive "using" is suitable (my opinion) esp. with ISRoutines to prevent
    them from pushing big load onto the (very limited) stack. It is also useful
    for functions called from ISR. Using "using" :-) for other common functions
    seems to me a bit "violent".

    Best wishes

Reply
  • The discussed directives have, as far as I know, the meaning I have explained.
    NOAREGS disables absolute register access, while AREGS enables (but not forces) it.
    When enabled, the compiler decides whether to use it or not in a particular
    situation ("is it advantageous or not?"). It doesn't mean that the addressing method
    unconditionally changes to absolute register accesses in every case.
    See your compiled programs in my previous post. You obtain the same result
    either you use AREGS or NOAREGS, because in both these examples NOAREGS
    option "prevails". There is no reason for absolute register access there.
    That's why it is not used even if AREGS option is selected.


    "But in the manual it is said that with "NOAREGS" one function could be called
    by another functions using different register bank..."


    In my opinion it is confusing (if not even wrong)
    as far as passing parameters or return values in registers are concerned.


    I suppose you mean C51.pdf, page 24 (?):

    "This directive may be used for functions that are called from other
    functions using different register banks."


    or further, on page 124:

    "To make a function insensitive to the current register bank, the function must be
    compiled using the NOAREGS control directive. This would be useful for a
    function that was called from the main program and also from an interrupt
    function that uses a different register bank.
    Note:
    The Cx51 compiler does not and cannot detect a register bank mismatch
    between functions. Therefore, make sure that functions using alternate register
    banks call only other functions that do not assume a default register bank."


    and later, page 128:

    "Functions called from an interrupt procedure must function with the same
    register bank as the interrupt procedure. When the NOAREGS directive is
    not explicitly specified, the compiler may generate absolute register accesses
    using the register bank selected (by the using attribute or by the
    REGISTERBANK control) for that function. Unpredictable results may
    occur when a function assumes a register bank other than the one currently
    selected."


    Once more as to the function register bank in/dependance -
    for instance lets assume 2 functions:

    a) func1() compiled with NOAREGS pragma,
    containing "mov r7,a" instruction in its body,
    the resulting code is 0xFF

    b) func2() compiled with AREGS pragma,
    containing corresponding to the above "mov ar7,a" instruction in its body,
    the resulting codes are 0xF5 0x17 if register bank used at compile time was 2

    if current register bank for both functions at calling time is, say, 1,
    then func1() will always write in R7 of the current register bank
    while func2() will write in absolute address 17H which is probably not the intention

    This is, among others, what they meant "To make a function insensitive
    to the current register bank..."


    In my opinion the RB independence concerns rather the body of the function
    than parameters or return values passed in registers.
    The directive "using" is suitable (my opinion) esp. with ISRoutines to prevent
    them from pushing big load onto the (very limited) stack. It is also useful
    for functions called from ISR. Using "using" :-) for other common functions
    seems to me a bit "violent".

    Best wishes

Children