Я читаю этот ответ Каков формат структуры x86_64 va_list? , где упоминается член va_list
-> void *reg_save_area
, который должен быть адресом начала зарегистрируйте область сохранения. Но, насколько мне известно, в ABI нет области сохранения, поскольку все переданные аргументы не передаются, а сохраняются в регистре rdi,rsi,rdx,rcx,..
, что означает, что адрес не имеет смысла для меня, так как аргумент не передается в память . Я попытался увидеть его в сборке, поэтому я скомпилировал код из моего предыдущего вопроса Что -fverbose-asm пытается сказать в сборке? :
#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);
}
и получил:
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
Итак, теперь void *overflow_arg_area
указывает на 16(%rbp)
, но там ничего нет, поскольку все аргументы были сохранены в rdi,rsi,rdx
(3 аргумента). Может кто-нибудь объяснить, почему * overflow_arg_area указывает на случайный 16(%rbp)
?