简体   繁体   中英

about linux kernel __asm__ grammar

When I analyzed kernel code from include/asm/system.h of linux 0.11 kernel,

I have had some question.

There are some code like

#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)

It needs to set idt. some code that set idt use the macro like

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);

I have question about c-grammar at this point:"o" (*((char ) (gate_addr))). and "o" ( (4+(char *) (gate_addr)))

Does this code make the output one byte???

for example If &idt[0] is 0x00006620, Does "o" (*((char *) (gate_addr))) code make output like 0x20 because of char type??

but, It seems that the code makes the output like 0x00006620.

I don't know about this asm grammar. why does this asm code work like this??? what is the rule and grammar?

That isn't "C grammar" per se, that is part of GCC's extended asm syntax . The "o" is a constraint that limits the access method that the compiler will attempt to use when that variable is referenced in the assembly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM