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

va_start/va_arg: how do these work? Have problems with them.

Hi,

First of all: I'm using a XE167FM-72 microcontroller.
I'm stuck using the va_* family of functions.
I've looked into the generated assembler code, it seems that it passes the first parameters directly via registers, and put the rest on the userstack.

Example for a call:

task7_va(3,2,3,4,0,0,0,0); give me

00C0512A E004      MOV      R4,#0x00
00C0512C 8840      MOV      [-R0],R4
00C0512E E004      MOV      R4,#0x00
00C05130 8840      MOV      [-R0],R4
00C05132 E004      MOV      R4,#0x00
00C05134 8840      MOV      [-R0],R4
00C05136 E00C      MOV      R12,#0x00
00C05138 E04B      MOV      R11,#0x04
00C0513A E03A      MOV      R10,#0x03
00C0513C E029      MOV      R9,#0x02
00C0513E E038      MOV      R8,#0x03
00C05140 DAC0CC4F  CALLS    task7_va(0xC04FCC)

va_start(vl,count); in task7_va give me

00C0501A E6F41000  MOV      R4,#0x0010
00C0501E 0040      ADD      R4,R0
00C05020 66F4FF3F  AND      R4,#0x3FFF
00C05024 F2F504FE  MOV      R5,DPP3:0x3E04 //comment from me: loads DPP2 (0x380) into R5
00C05028 C4400200  MOV      [R0+#0x0002],R4
00C0502C C4500400  MOV      [R0+#0x0004],R5

arg = va_arg(vl,int); in task7_va give me

00C05036 E026      MOV      R6,#0x02
00C05038 D4500400  MOV      R5,[R0+#0x0004]
00C0503C D4400200  MOV      R4,[R0+#0x0002]
00C05040 0046      ADD      R4,R6
00C05042 C4400200  MOV      [R0+#0x0002],R4
00C05046 D4500400  MOV      R5,[R0+#0x0004]
00C0504A D4400200  MOV      R4,[R0+#0x0002]
00C0504E E026      MOV      R6,#0x02
00C05050 2046      SUB      R4,R6
00C05052 DC55      EXTP     R5,#2
00C05054 A9C4      MOVB     RL6,[R4]
00C05056 F4D40100  MOVB     RH6,[R4+#0x0001]
00C0505A F046      MOV      R4,R6
00C0505C C4400C00  MOV      [R0+#0x000C],R4

I don't see where the direct access to the registers r8...r12 are happening.
I have problems not getting the correct values, that's why I'm digging into this a bit deeper.
I hope that it doesn't make any assumption where the userstack (R0) and the register bank (CP) are (there are of course an legal positions for the microcontroller point of view) - I need to change them via assembler.

Best regards,
Michael Fritscher

Parents
  • Looks like you just found those accesses to the arguments passed in registers r8 etc. that you missed earlier, doesn't it?

    It appears as if those pushes are intended to set up the environment to allow the va_* macros to work. They push register arguments on the stack, where va_start/va_arg can acces them uniformly with those that were passed on the stack from the start.

    This kind of push-back operation is part of the price to be paid for the efficiency of partly register-based calling conventions.

Reply
  • Looks like you just found those accesses to the arguments passed in registers r8 etc. that you missed earlier, doesn't it?

    It appears as if those pushes are intended to set up the environment to allow the va_* macros to work. They push register arguments on the stack, where va_start/va_arg can acces them uniformly with those that were passed on the stack from the start.

    This kind of push-back operation is part of the price to be paid for the efficiency of partly register-based calling conventions.

Children