Mim*_*mmo 1 assembly gcc x86-64 inline-assembly osdev
我试图从C调用一些汇编代码。最近,我在将程序从x86切换到x86-64之前开始工作。我有以下代码:
__asm__ __volatile__("lidtl (%0)" : : "r" (&idt_reg));
Run Code Online (Sandbox Code Playgroud)
哪里&idtreg是对结构的引用。用GCC进行编译会给我这个错误:
'lidt'的无效指令后缀
当我添加$令牌时:
__asm__ __volatile__("lidtl $(%0)" : : "r" (&idt_reg));
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
非法的立即寄存器操作数(%rax)
为什么会出现此问题,我该如何解决?
In 32-bit code the memory operand for LIDT is 32-bit. In AT&T syntax the L instruction suffix forces the assembler to always assume long (32-bit). In 64-bit code the memory operands are 64-bit. If you use an instruction suffix then it has to be Q (quadword). A quadword is 64-bits.
The assembler is smart enough to know the size of LIDT depending on whether it is generating 32-bit or 64-bit code. The better alternative is to let the assembler deduce the size by leaving off the size in the instruction suffix. Simply use LIDT instead. The code could look like:
__asm__ ("lidt %0" : : "m" (idt_reg));
Run Code Online (Sandbox Code Playgroud)
I've dropped volatile as it is implicit when there are no output operands. I use an m (memory operand) as a constraint to avoid problems with passing memory addresses through a register. Passing an address through a register requires a memory clobber or similar mechanism to ensure the data at that address is available in memory before the inline assembly is emitted. From the GCC documentation:
The "memory" clobber tells the compiler that the assembly code performs memory reads or writes to items other than those listed in the input and output operands (for example, accessing the memory pointed to by one of the input parameters). To ensure memory contains correct values, GCC may need to flush specific register values to memory before executing the asm.
If you did use an r constraint (there is no need to) then the proper code would have been:
__asm__ ("lidt (%0)" : : "r" (&idt_reg) : "memory");
Run Code Online (Sandbox Code Playgroud)
L or Q instruction suffix this version should compile whether generating 32-bit or 64-bit programs.