3

我正在努力在 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 有其他方法,但这不是我要在这里回答的问题;我只是想弄清楚宏是否可以扩展为宏参数。

4

2 回答 2

4

The arguments themselves are expanded, but the number of arguments must match the macro definition. You'll need an extra macro to make it work:

#define IDT1(x) SETUP_IDT_ENTRY(x)

IDT1(M_DIVIDE)

More info here and here.

于 2013-01-31T16:48:04.660 回答
2

它可以通过另一层间接来完成:

#define PLEASE_SETUP_IDT_ENTRY(...) SETUP_IDT_ENTRY(__VA_ARGS__)
// the delicate, civilized call
PLEASE_SETUP_IDT_ENTRY(M_DIVIDE)

(如果我们想要一个新的变体只接受一个参数,就不需要变长宏。上面的定义接受一个多个参数)。

于 2013-01-31T16:47:09.720 回答