#include
#include
#if __GNUC__
#if __x86_64__
#define ENVIRONMENT64
#else
#define ENVIRONMENT32
#endif
#endif
#if defined(ENVIRONMENT64)
long add(long num, ...)
{
long sum = 0, i, tmp;
/*
(gdb) pt va_list
type = struct __va_list_tag {
unsigned int gp_offset;
unsigned int fp_offset;
void *overflow_arg_area;
void *reg_save_area;
} [1]
*/
va_list va;
printf("ENVIRONMENT64\n");
/*
(gdb) p va
$2 = {{
gp_offset = 8,
fp_offset = 48,
overflow_arg_area = 0x7fffffffe520,
reg_save_area = 0x7fffffffe460
}}
(gdb) x/6g va.reg_save_area // 这里g表示一次打印8字节
0x7fffffffe460: 0x0000000000000001 0x0000000000000002
0x7fffffffe470: 0x0000000000000003 0x0000000000000004
0x7fffffffe480: 0x0000000000000005 0x0000000000000006
(gdb) x/2g va.overflow_arg_area
0x7fffffffe520: 0x0000000000000007 0x0000000000000008
*/
va_start(va, num);
for (i = 0; i < num; i++) {
tmp = va_arg(va, int);
sum += tmp;
printf("%ld ", tmp);
}
printf("\n");
va_end(va);
return sum;
}
#endif
#if defined(ENVIRONMENT32)
long add(long num, ...)
{
long sum = 0, i, tmp;
long *arg = &num + 1;
printf("ENVIRONMENT32\n");
for (i = 0; i < num; i++)
{
tmp = arg[i];
sum += tmp;
printf("%ld ", tmp);
}
printf("\n");
return sum;
}
#endif
int main()
{
/* ENVIRONMENT32, 使用栈来传参
0x080484f5 : movl $0x8,0x1c(%esp)
0x080484fd : movl $0x7,0x18(%esp)
0x08048505 : movl $0x6,0x14(%esp)
0x0804850d : movl $0x5,0x10(%esp)
0x08048515 : movl $0x4,0xc(%esp)
0x0804851d : movl $0x3,0x8(%esp)
0x08048525 : movl $0x2,0x4(%esp)
0x0804852d : movl $0x7,(%esp)
0x08048534 : call 0x804847d
*/
/* ENVIRONMENT64, 使用寄存器+栈(默认calling convention)
0x0000000000400711 : movl $0x8,0x8(%rsp)
0x0000000000400719 : movl $0x7,(%rsp)
0x0000000000400720 : mov $0x6,%r9d
0x0000000000400726 : mov $0x5,%r8d
0x000000000040072c : mov $0x4,%ecx
0x0000000000400731 : mov $0x3,%edx
0x0000000000400736 : mov $0x2,%esi
0x000000000040073b : mov $0x7,%edi
0x0000000000400740 : mov $0x0,%eax
0x0000000000400745 : callq 0x4005bd
*/
long sum = add(7, 2, 3, 4, 5, 6, 7, 8);
printf("sum is %ld\n", sum);
return 0;
}