I have compiled this function:
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);}
into this assembly:
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 #, movaps %xmm0, -128(%rbp) #, ....L7:# a.c:7: va_start(args, len); 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 leaq -176(%rbp), %rax #, tmp101 movq %rax, -192(%rbp) # tmp101, MEM[(struct [1] *)&args].reg_save_area# a.c:9: for(int i =0; i<len ; i++) movl $0, -180(%rbp) #, i# a.c:9: for(int i =0; i<len ; i++) jmp .L3 #.L6:# a.c:11: int val = va_arg(args,int); movl -208(%rbp), %eax # MEM[(struct *)&args].gp_offset, D.2882 cmpl $47, %eax #, D.2882 ja .L4 #,# a.c:11: int val = va_arg(args,int); ...
I know it looks like mess, but there are some part of the output I am interested in. Specially lines like this:
movl $8, -208(%rbp) #, MEM[(struct [1] *)&args].gp_offset
I would try to analyse it:
MEM[...]
-> could represent a whole memory as an array (an addresses as a index)MEM[(struct[1]*)...]
-> could represent a type, which this type itself is a member of some unknown structstruct[1]*
gives then pointer to a type of the second member of that structMEM[(struct[1]*)&args]
-> once the data type (length) is specified (struct[1]*
), it reside at address of variableargs
, so know we know, where to startMEM[(struct[1]*)&args].gp_offset
-> So we have a type, a start address which together gives us a index to global memory table, which obtain a "some value" upon which we want to access to getgp_offset
?
Is my surmises correct? What members or functions (or what it is) are the members gained ->
gp_offset, fp_offset, overflow_arg_area, reg_save_area, ...
Can I find an implementation of them to see what they does? or are they documented under compiler internals?