我正在努力在x86程序集中手动构建IDT表。我在.S文件中使用C预处理器定义了以下宏:
// sets up an entry in the idt for a trap type
#define SETUP_IDT_ENTRY( name, num, istrap, segment, dpl ) \
lea name, %edx; \
movl $(KCODE << 16), %eax; \
movw $0x8e00, %dx; \
lea (idt + (8 * num)), %edi; \
movl %eax, (%edi); \
movl %edx, 4(%edi);
// sample set of args to a call to setup_dt_entry
#define M_DIVIDE _t_divide_ep, T_DIVIDE, 0, KCODE, 0
// the call
SETUP_IDT_ENTRY( M_DIVIDE )
然而,gcc抱怨:error: macro "SETUP_IDT_ENTRY" requires 5 arguments, but only 1 given
我认为#define'd函数的#define'd参数在评估函数调用之前已经扩展,在这种情况下M_DIVIDE
会扩展为所需的五个参数,SETUP_IDT_ENTRY
会很高兴。我尝试了各种括号组合,似乎没有任何工作;有没有办法使这项工作?
注意:我知道在x86程序集中有另外的方法来构建IDT,但这不是我想在这里回答的问题;我只想弄清楚宏是否可以扩展为宏参数。
答案 0 :(得分:4)
参数本身已扩展,但参数的数量必须与宏定义匹配。你需要一个额外的宏来使它工作:
#define IDT1(x) SETUP_IDT_ENTRY(x)
IDT1(M_DIVIDE)
答案 1 :(得分:2)
可以使用另一层间接来完成:
#define PLEASE_SETUP_IDT_ENTRY(...) SETUP_IDT_ENTRY(__VA_ARGS__)
// the delicate, civilized call
PLEASE_SETUP_IDT_ENTRY(M_DIVIDE)
(如果我们想要一个新变量接受一个且只有一个参数,则不需要Variadic宏。上面的定义接受一个或多个参数)。