I am reading this answer What is the format of the x86_64 va_list structure?, where there is mention a member of va_list -> void *reg_save_area, which should be a address of start of the register save area. But as far as I know, there is no save area defined in ABI, since all arguments passed are not pushed but rather saved on register rdi,rsi,rdx,rcx,.., which mean the address does not make sense to me, since no argument is passed to memory. I have tried to see it in assembly, So I have compiled code from my previous question What is -fverbose-asm trying to say in assembly?:
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
void print_ints(int len, ...){
va_list args;
va_start(args, len);
for(int i =0; i<len ; i++)
{
int val = va_arg(args,int);
printf("i:%i\tval:%i\n",i,val);
}
va_end(args);
}
int main(){
print_ints(2,1,2);
}
and got:
print_ints:
pushq %rbp #
movq %rsp, %rbp #,
subq $224, %rsp #,
movl %edi, -212(%rbp) # len, len
movq %rsi, -168(%rbp) #,
movq %rdx, -160(%rbp) #,
movq %rcx, -152(%rbp) #,
movq %r8, -144(%rbp) #,
movq %r9, -136(%rbp) #,
testb %al, %al #
je .L7 #,
...
movl $8, -208(%rbp) #, MEM[(struct [1] *)&args].gp_offset
movl $48, -204(%rbp) #, MEM[(struct [1] *)&args].fp_offset
leaq 16(%rbp), %rax #, tmp100
movq %rax, -200(%rbp) # tmp100, MEM[(struct [1] *)&args].overflow_arg_area
...
main:
pushq %rbp #
movq %rsp, %rbp #,
# a.c:19: print_ints(2,1,2);
movl $2, %edx #,
movl $1, %esi #,
movl $2, %edi #,
movl $0, %eax #,
call print_ints # THERE IS NO ARGUMENT PASSED TO STACK, 16(%rbp) does not make sense then to be address for reg_save_area
So now, the void *overflow_arg_area points to the 16(%rbp), but there is nothing, since all argument where saved to rdi,rsi,rdx(3 arguments). Can someone explain, why does *overflow_arg_area points to random 16(%rbp)?