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

Stack

Hello,
I'm working on the XC164X µc and I've a question concerning the storage of registers in stack when interrupt occur.

The function is written in c language

void ItFunc (void) interrupt 14
{ funcCode ();
}

The pre-processor code is as follow:

ItFunc PROC INTERRUPT = 14 GLOBAL ItFunc
; FUNCTION ItFunc (BEGIN RMASK = @0x3FFF)

SCXT DPP3,#3

PUSH DPP0

SCXT MDC,#16

PUSH MDH

PUSH MDL

MOV [-R0],R1

MOV [-R0],R2

MOV [-R0],R3

MOV [-R0],R4

MOV [-R0],R5

MOV [-R0],R6

MOV [-R0],R7

MOV [-R0],R8

MOV [-R0],R9

MOV [-R0],R10

MOV [-R0],R11

MOV [-R0],R12

; line 234: funcCode ();

CALL funcCode

?C0005:

MOV R12,[R0+]

MOV R11,[R0+]

MOV R10,[R0+]

MOV R9,[R0+]

MOV R8,[R0+]

MOV R7,[R0+]

MOV R6,[R0+]

MOV R5,[R0+]

MOV R4,[R0+]

MOV R3,[R0+]

MOV R2,[R0+]

MOV R1,[R0+]

POP MDL

POP MDH

POP MDC

POP DPP0

POP DPP3

RETI

; FUNCTION ItFunc (END RMASK = @0x3FFF)

ItFunc ENDP

?PR?BS_TST ENDS

As shown in this pre-processor code, we use the register R0 to save the registers R1—R12.
I'd like to store the registers using the instruction PUSH R1.
How can I do this? Which directive could I use that the compiler store the registers in stack using the instruction "PUSH R1" and not using "MOV [-R0], R1"

Thanks

Parents Reply Children
  • I don't need the register R0, but just I'd like to know if there are other directives in keil to push the register in stack using PUSH and not mov R0.

    that's it

  • You have defined that you want to use the "User Stack" with is R0. If you want to use the PUSH/POP then you want to use the "System Stack".

  • the keil software, uses the R0 register for user stack, so we lose this R0 register, and is worthy to use the PUSH instruction to store registers in stack.

    I don't need the register R0, but just I'd like to know if there are other directives in keil to push the register in stack using PUSH and not mov R0.

    Why is it "worthy"/useful to use the push instruction and have R0 available if you don't need it?

    If you check the user manual, PUSH is used to push registers on the SYSTEM stack. The 'mov R0' puts the data on the USER stack, which might be bigger. I can see why the compiler will use the -user- stack instead of using PUSH'es which cause everything to be put on the SYSTEM stack.

    See also:
    http://www.keil.com/support/man/docs/c166/c166_ap_stack.htm

    http://www.keil.com/support/man/docs/c166/c166_ap_regusage.htm

    http://www.keil.com/support/man/docs/c166/c166_noframe.htm

    http://www.keil.com/support/man/docs/c166/c166_le_regbank.htm

    --
    Joost

  • I give you an example

    In the document that joost gives to me « http://www.keil.com/support/man/docs/c166/c166_noframe.htm"

    We find this example:

    1 int i1, i2, i3;

    2 3 void intr_func1 (void) interrupt 0x21 {

    4 1 i1 = i2 * i3;

    5 1 } 6

    7 #pragma NOFRAME

    8 void intr_func2 (void) interrupt 0x22 {

    9 1 i1 = i2 * i3;

    10 1 }

    ASSEMBLY LISTING OF GENERATED OBJECT CODE

    ; FUNCTION intr_func1 (BEGIN RMASK = @0x2030)

    ; SOURCE LINE # 3

    0000 C6871000 SCXT MDC,#010H

    0004 EC06 PUSH MDH

    0006 EC07 PUSH MDL

    0008 ECF4 PUSH R4

    000A ECF5 PUSH R5

    ; SOURCE LINE # 4

    000C F2F50000 R MOV R5,i3

    0010 F2F40200 R MOV R4,i2

    0014 0B45 MUL R4,R5

    0016 F2F40EFE MOV R4,MDL

    001A F6070400 R MOV i1,MDL

    ; SOURCE LINE # 5

    001E FCF5 POP R5

    0020 FCF4 POP R4

    0022 FC07 POP MDL

    0024 FC06 POP MDH

    0026 FC87 POP MDC

    0028 FB88 RETI

    ; FUNCTION intr_func1 (END RMASK = @0x2030)

    ; FUNCTION intr_func2 (BEGIN RMASK = @0x2030)

    ; SOURCE LINE # 8

    ; SOURCE LINE # 9

    002A F2F50000 R MOV R5,i3

    002E F2F40200 R MOV R4,i2

    0032 0B45 MUL R4,R5

    0034 F2F40EFE MOV R4,MDL

    0038 F6070400 R MOV i1,MDL

    ; SOURCE LINE # 10

    003C FB88 RETI

    ; FUNCTION intr_func2 (END RMASK = @0x2030)

    ;
    ; ;
    ; ;
    ; ;

    Let's concentrate on function intr_func1

    ;
    ; ;

    1 int i1, i2, i3;

    2

    3 void intr_func1 (void) interrupt 0x21 {

    4 1 i1 = i2 * i3;

    5 1 }

    ASSEMBLY LISTING OF GENERATED OBJECT CODE

    ; FUNCTION intr_func1 (BEGIN RMASK = @0x2030)

    ; SOURCE LINE # 3

    0000 C6871000 SCXT MDC,#010H

    0004 EC06 PUSH MDH

    0006 EC07 PUSH MDL

    0008 ECF4 PUSH R4

    000A ECF5 PUSH R5

    ; SOURCE LINE # 4

    000C F2F50000 R MOV R5,i3

    0010 F2F40200 R MOV R4,i2

    0014 0B45 MUL R4,R5

    0016 F2F40EFE MOV R4,MDL

    001A F6070400 R MOV i1,MDL

    ; SOURCE LINE # 5

    001E FCF5 POP R5

    0020 FCF4 POP R4

    0022 FC07 POP MDL

    0024 FC06 POP MDH

    0026 FC87 POP MDC

    0028 FB88 RETI

    ; FUNCTION intr_func1 (END RMASK = @0x2030)

    ;
    ; ;
    ; ;

    ;
    ;

    We see in that the ASSEMBLY LISTING OF GENERATED
    OBJECT CODE stores the register R4 and R5 using PUSH
    R4 and PUSH R5.

    In my case when I've written the same function intr_func1, that the ASSEMBLY LISTING OF GENERATED OBJECT CODE stores the register R4 using MOV [-R0],R4

    ;
    ; ;
    ;

    intr_func1 PROC INTERRUPT = 33

    GLOBAL intr_func1

    ; FUNCTION intr_func1 (BEGIN RMASK = @0x2030)

    SCXT MDC,#16

    PUSH MDH

    PUSH MDL

    MOV [-R0],R4

    MOV [-R0],R5

    ; line 997:

    ; line 998:

    ; line 999: i1 = i2 * i3;

    MOV R5,WORD i3

    MOV R4,WORD i2

    MUL R4,R5

    MOV WORD i1,MDL

    ; line 1000: }

    MOV R5,[R0+]

    MOV R4,[R0+]

    POP MDL

    POP MDH

    POP MDC

    RETI

    ; FUNCTION intr_func1 (END RMASK = @0x2030)

    intr_func1 ENDP

    ?PR?OS_TEST ENDS

    ;
    ; ;
    ; ;

    So my question is, I'd like to know how in the first case the compiler store R4 in stack using PUSH, and why in my case he store R4 using MOV [-R0],R4

    I hope now is more clear

  • Please post code in the correct way - the above text is unreadable.

    There are many, many thousands of decisions the compiler makes when it generates it's code. However, that is not something you should care about, just as you shouldn't care about the algorithm for controlling the ignition system in your car.

    Tou are working at the wrong conceptual level, and it doesn't matter how many questions you ask - and how many answers you receive. There will still be thousands of other issues where the compiler decides what to do, and when.

  • the code exist in « http://www.keil.com/support/man/docs/c166/c166_noframe.htm"

    just I've made a copy of this code.

    the compiler don't decides what to do, we use directives and configuration to assisit compiler what to do.

    so please, the question is clear, why turn arround??

  • No, the compiler really do decide what to do. We write source code to inform it what we want solved, and we use directives to give it hints about how to solve it.

    If it was you who decided what to do, then you wouldn't need to buy the compiler, since you would not have any need for it. The way you decide what to do, is by writing the program in assembler.

  • just I've made a copy of this code.

    Per Westermark is refering to using the pre tags to post code on the forum.

  • the compiler don't decides what to do, we use directives and configuration to assisit compiler what to do.

    so please, the question is clear, why turn arround??

    I understand what your trying to do; give a hint to the compiler to use PUSH (system stack) instead of MOV (user stack). But it's a hint so the compiler can still decide to do otherwise.

    Could you answer me/us this: -why- do you want the compiler to use PUSH instead of MOV? I don't see why it's important in the first place.

  • Is not important if we store registers using push or mov R0, just i'm curious to know why there are two possibility to stores registers in stack. so I think there's an option to check off to tell compiler when using push or mov R0.

  • thanks for advising me to use pre> to post code, it's the first time that I post in this forum.

  • There is checkbox in the Options for target/C166

    "Save temporary variables on User Stack"
    If it is checked, then all registers are placed in User Stack, i.e commands like mov [-R0], Rx are used.
    If unchecked, then push/pop commands are used instead.

  • There is checkbox in the Options for target/C166

    Thanks Andrey!

    For those people who do not use the IDE :-) it's the SAVESYS and SAVEUSR compiler directive. I completly missed those...

    See
    http://www.keil.com/support/man/docs/c166/c166_cm_directives.htm

    Thanks MOMO, I learned something new because of your post.

    --
    Joost

  • yes, finally

    thanks for you