2015-11-07 156 views
0

当我从linux 0.11内核的include/asm/system.h分析内核代码时,我有过一些问题。关于linux内核__asm__语法

有喜欢

#define _set_gate(gate_addr,type,dpl,addr) \ 
__asm__ ("movw %%dx,%%ax\n\t" \ 
    "movw %0,%%dx\n\t" \ 
    "movl %%eax,%1\n\t" \ 
    "movl %%edx,%2" \ 
    : \ 
    : "i" ((short) (0x8000+(dpl<<13)+(type<<8))), \ 
    "o" (*((char *) (gate_addr))), \ 
    "o" (*(4+(char *) (gate_addr))), \ 
    "d" ((char *) (addr)),"a" (0x00080000)) 

#define set_intr_gate(n,addr) \ 
    _set_gate(&idt[n],14,0,addr) 

#define set_trap_gate(n,addr) \ 
    _set_gate(&idt[n],15,0,addr) 

#define set_system_gate(n,addr) \ 
    _set_gate(&idt[n],15,3,addr) 

需要设置IDT一些代码。 一些代码,设置IDT使用像

void trap_init(void) 
{ 
    int i; 

    set_trap_gate(0,&divide_error); 
    set_trap_gate(1,&debug); 
    set_trap_gate(2,&nmi); 
    set_system_gate(3,&int3); /* int3-5 can be called from all */ 
    set_system_gate(4,&overflow); 
    set_system_gate(5,&bounds); 
    set_trap_gate(6,&invalid_op); 
    set_trap_gate(7,&device_not_available); 

我对C-语法问题宏在这一点上: “O”(*((字符)(gate_addr)))。和“o”((4+(char *)(gate_addr)))

这段代码是否使输出成为一个字节?

例如,如果& idt [0]是0x00006620,由于char类型,“o”(*((char *)(gate_addr)))代码是否使输出像0x20一样?

但是,看起来代码使输出像0x00006620。

我不知道这个asm语法。为什么这个asm代码像这样工作?规则和语法是什么?

+0

除了伊格纳西奥所说的几点:1)这个代码的输出是由汇编器决定的。 'movl %% eax,%1'会将eax中的32位写入%1中的内存位置(又名'(*((char *)(gate_addr)))')。 2)这个asm看起来不太适合我。 %1是一个输入(唯一)参数。写信给它看起来很可疑。 –

+0

@DavidWohlferd可能是为什么该代码只存在于早期的Linux内核中。这绝对是可疑的。 –

回答

0

这不是“C语法”本身,它是GCC的extended asm syntax的一部分。 "o"constraint,它限制编译器在程序集中引用该变量时尝试使用的访问方法。

+0

引用“简单约束”部分和“o”约束实际是什么(如果内存操作数不可关闭,是允许的) –