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)
?