Keil Logo

C51: Why Does VA_ARGS Work?

Information in this article applies to:

  • C51 Version 5.50


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?


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\n", 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.


  • Refer to va_list in the Cx51 User's Guide.
  • Refer to MAXARGS in the Cx51 User's Guide.

Last Reviewed: Thursday, February 25, 2021

Did this article provide the answer you needed?
Not Sure
  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.