【问题标题】:about linux kernel __asm__ grammar关于linux内核__asm__语法
【发布时间】:2016-02-08 08:50:29
【问题描述】:

当我从linux 0.11内核的include/asm/system.h中分析内核代码时,

我有一些问题。

有一些类似的代码

#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" (*((char ) (gate_addr)))。和 "o" ((4+(char *) (gate_addr)))

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

例如,如果 &idt[0] 为 0x00006620,“o”(*((char *) (gate_addr))) 代码是否会因为 char 类型而产生类似 0x20 的输出??

但是,似乎代码使输出类似于 0x00006620。

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

【问题讨论】:

  • 除了伊格纳西奥所说的,还有几点: 1)这段代码“输出”的内容是由汇编程序决定的。 movl %%eax,%1 会将 eax 中的 32 位写入 %1 中的内存位置(又名 (*((char *) (gate_addr))))。 2)这个asm对我来说看起来不太合适。 %1 是输入(仅)参数。给它写信似乎很可疑。
  • @DavidWohlferd 可能是为什么该代码只存在于非常早期的 Linux 内核中。这绝对是可疑的。

标签: c linux assembly kernel


【解决方案1】:

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

【讨论】:

  • 同时引用simple constraint 部分以及o 约束实际上是什么(如果内存操作数可偏移,则允许使用)不是更有用吗
猜你喜欢
  • 2012-11-19
  • 1970-01-01
  • 2020-02-19
  • 1970-01-01
  • 1970-01-01
  • 2016-03-19
  • 2014-06-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多