0
asm("lidt (%0)" : : "p"(&idtr));

The above statement will be used to define an IDTR in my IA-32 operating system. For some reason though, the compiler chokes on it:

kernel/kernel.c:52:2: error: invalid 'asm': invalid expression as operand
  asm("lidt (%0)" : : "p"(&idtr));
  ^

Does anyone know what I'm doing wrong here? If you need any more context to answer my question, please say so and I will gladly provide it.

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
the_rover
  • 25
  • 4

1 Answers1

3

Apart from the instruction, you got every possible thing wrong. The correct way:

asm("lidt %0" : : "m"(idtr));
Jester
  • 56,577
  • 4
  • 81
  • 125
  • Thanks, but now I'm getting `/tmp/ccfk5J0f.s: Assembler messages: /tmp/ccfk5J0f.s:293: Error: missing ')' /tmp/ccfk5J0f.s:293: Error: junk \`(%esp))' after expression`. – the_rover Nov 30 '15 at 02:36
  • Show how `idtr` is defined. This method works, it's even [used in the linux kernel](https://github.com/torvalds/linux/blob/master/arch/x86/boot/pm.c#L98). – Jester Nov 30 '15 at 02:37
  • `IDTR idtr = (IDTR) {.size = sizeof(IDT), .offset = (uint32_t) &IDT};` where `IDT` is an array of IDT descriptors. – the_rover Nov 30 '15 at 02:38
  • Are you sure you removed the `()` and really just have `lidt %0`? I get exactly that error if I change it back to `lidt (%0)` which is **wrong**. – Jester Nov 30 '15 at 02:39
  • No, I didn't. Duh :p – the_rover Nov 30 '15 at 02:40
  • 1
    @mandatory-access-control: Do not use a _compound literal_ in an initialiser. It is only needed in a normal expression. And you should use the correct types when casting a pointer to an integer: `(u)intptr_t`. – too honest for this site Nov 30 '15 at 02:47