如何解释用于在tcc的stdarg.h中实现va_arg和va_start的代码?

时间:2016-05-22 03:32:58

标签: c++ c assembly compilation x86-64

struct __va_list_struct
{
    unsigned int gp_offset;
    unsigned int fp_offset;
    union {
        unsigned int overflow_offset;
        char* overflow_arg_area;
    };
    char* reg_save_area;
};

typedef struct __va_list_struct* va_list;

/* we use __builtin_(malloc|free) to avoid #define malloc tcc_malloc */
/* XXX: this lacks the support of aggregated types. */
#define va_start( ap, last )                                                  \
    ( ap = (va_list)__builtin_malloc ( sizeof ( struct __va_list_struct ) ),  \
      *ap = *(struct __va_list_struct*)( (char*)__builtin_frame_address ( 0 ) \
                                         - 16 ),                              \
      ap->overflow_arg_area                                                   \
      = ( (char*)__builtin_frame_address ( 0 ) + ap->overflow_offset ),       \
      ap->reg_save_area = (char*)__builtin_frame_address ( 0 ) - 176 - 16 )
#define va_arg( ap, type )                                                     \
    ( *(type*)( __builtin_types_compatible_p ( type, long double )             \
                    ? ( ap->overflow_arg_area += 16,                           \
                        ap->overflow_arg_area - 16 )                           \
                    : __builtin_types_compatible_p ( type, double )            \
                          ? ( ap->fp_offset < 128 + 48                         \
                                  ? ( ap->fp_offset += 16,                     \
                                      ap->reg_save_area + ap->fp_offset - 16 ) \
                                  : ( ap->overflow_arg_area += 8,              \
                                      ap->overflow_arg_area - 8 ) )            \
                          : ( ap->gp_offset < 48                               \
                                  ? ( ap->gp_offset += 8,                      \
                                      ap->reg_save_area + ap->gp_offset - 8 )  \
                                  : ( ap->overflow_arg_area += 8,              \
                                      ap->overflow_arg_area - 8 ) ) ) )

第一个结构的定义特别让我困惑。

下一个是宏 - va_start()

决赛是宏观的 - va_arg()

以上所有内容都在x86_64平台中使用...

你能解释一下这段代码的作用吗?

0 个答案:

没有答案