ARM Technical Support Knowledge Articles

WHY DOES VA_ARGS WORK?

Applies to: C51 C Compiler

Answer

Information in this article applies to:


QUESTION

I am planning on using the va_args macros in my code, however, the C-compiler likes to pass up to 5 parameters in registers. This would seem to break the va_args macro!

Since the va_list macro needs to get the address of an argument, if the argument is in a register there is a problem (because we cannot take the address of a register).

How does one handle this situation?

ANSWER

Arguments in the variable-length portion of the argument list are never placed in registers, so the problems you anticipate don't occur.

For example, consider the following program:

#include "reg51.h"
#include "stdio.h"
#include "stdarg.h"

int print_strings (
  unsigned char count,
  ...)
{
va_list arg_list;

va_start (arg_list, count);

while (count--)
  {
  printf ("%s
", va_arg (arg_list, char *));
  }

va_end (arg_list);
}

void main (void)
{
SCON  = 0x50;
TMOD |= 0x20;
TH1   = 221;
TR1   = 1;
TI    = 1;

while (1)
  {
  print_strings (4, "This", "Is", "A", "TEST");
  }
}

The code generated for the print_strings function call appears as follows:

  34   2        print_strings (4, "This", "Is", "A", "TEST");
000D 7F04          MOV     R7,#04H
000F 7500FF  R     MOV     ?_print_strings?BYTE+01H,#0FFH
0012 750000  R     MOV     ?_print_strings?BYTE+02H,#HIGH ?SC_4
0015 750000  R     MOV     ?_print_strings?BYTE+03H,#LOW ?SC_4
0018 7500FF  R     MOV     ?_print_strings?BYTE+04H,#0FFH
001B 750000  R     MOV     ?_print_strings?BYTE+05H,#HIGH ?SC_9
001E 750000  R     MOV     ?_print_strings?BYTE+06H,#LOW ?SC_9
0021 7500FF  R     MOV     ?_print_strings?BYTE+07H,#0FFH
0024 750000  R     MOV     ?_print_strings?BYTE+08H,#HIGH ?SC_12
0027 750000  R     MOV     ?_print_strings?BYTE+09H,#LOW ?SC_12
002A 7500FF  R     MOV     ?_print_strings?BYTE+0AH,#0FFH
002D 750000  R     MOV     ?_print_strings?BYTE+0BH,#HIGH ?SC_14
0030 750000  R     MOV     ?_print_strings?BYTE+0CH,#LOW ?SC_14
0033 120000  R     LCALL   _print_strings

Note that the arguments that are part of the variable length list are not placed in registers.

MORE INFORMATION

Article last edited on: 2005-07-15 10:37:21

Rate this article

[Bad]
|
|
[Good]
Disagree? Move your mouse over the bar and click

Did you find this article helpful? Yes No

How can we improve this article?

Link to this article
Copyright © 2011 ARM Limited. All rights reserved. External (Open), Non-Confidential