Assembly 错误:操作码和操作数的组合无效-nasm

Assembly 错误:操作码和操作数的组合无效-nasm,assembly,x86,nasm,osdev,Assembly,X86,Nasm,Osdev,我正在创建一个小例程,用lidt指令加载idtr寄存器。 我已经创建了这个代码- global load_idt load_idt: mov eax, esp add eax, 4 lidt eax ;<-----------------LINE 9 ret 我的编译命令是- nasm kernel/kernel_start.asm -f elf32 -o kernel/kernel_start.o 有人能指出这个程序中的错误吗?idtr寄存器必

我正在创建一个小例程,用
lidt
指令加载
idtr
寄存器。 我已经创建了这个代码-

global load_idt

load_idt:
    mov eax, esp
    add eax, 4
    lidt eax    ;<-----------------LINE 9
    ret
我的编译命令是-

nasm kernel/kernel_start.asm -f elf32 -o kernel/kernel_start.o

有人能指出这个程序中的错误吗?

idtr寄存器必须加载两条信息:指向描述符表的指针和前者的大小(字节减1)

因此,正如所述,唯一有效的形式是
LGDT m16&32
,其中
m16&32
是指向内存位置的指针,该内存位置包含16位大小和32位基指针

引用英特尔

源操作数指定包含基址和中断描述符限制的6字节内存位置 桌子

请注意,大小在基址之前

如果我是你,我会适当地使用C使装配最小化。
例如,使用一个结构来表示IDT基和限制,然后通过值将其传递给汇编中编写的函数。
这也是最罕见的情况,所以你可以考虑它。

/* IDT descriptor */
struct desc_t;

/* IDT */
struct __attribute__ ((__packed__)) IDT
{
   uint16_t size;
   struct desc_t* table;
};

/* Declaration of assembly function */
void set_idt(struct IDT idt);


;Parameters in order of push
;
;   struct IDT idt
;
_set_idt:
 lidt [esp+4]
 ret

琐事


从技术上讲,
lidt eax
是可编码的,使用值为0d8h的ModR/M字节(011b用于reg字段作为扩展操作码,11b和000b用于mod和r/M字段以使用
eax
),但如果使用寄存器源,
lidt
将生成#UD(实际上,
lidteax
被用于AMD-v的
vmrun

idtr寄存器必须加载两条信息:指向描述符表的指针和前者的大小(字节减1)

因此,正如所述,唯一有效的形式是
LGDT m16&32
,其中
m16&32
是指向内存位置的指针,该内存位置包含16位大小和32位基指针

引用英特尔

源操作数指定包含基址和中断描述符限制的6字节内存位置 桌子

请注意,大小在基址之前

如果我是你,我会适当地使用C使装配最小化。
例如,使用一个结构来表示IDT基和限制,然后通过值将其传递给汇编中编写的函数。
这也是最罕见的情况,所以你可以考虑它。

/* IDT descriptor */
struct desc_t;

/* IDT */
struct __attribute__ ((__packed__)) IDT
{
   uint16_t size;
   struct desc_t* table;
};

/* Declaration of assembly function */
void set_idt(struct IDT idt);


;Parameters in order of push
;
;   struct IDT idt
;
_set_idt:
 lidt [esp+4]
 ret

琐事


从技术上讲,
lidt eax
是可编码的,使用值为0d8h的ModR/M字节(011b用于reg字段作为扩展操作码,11b和000b用于mod和r/M字段以使用
eax
),但如果使用寄存器源,
lidt
将生成#UD(事实上,
lidteax
被用于AMD-v的
vmrun

助记符是
lidtm16和32
…你的意思是
lidt[eax]
?我想用
load_idt()
调用C中的函数。我必须使用
[eax]
?它不是指向idtr的值而不是它的地址吗?@tommylee2kmemonic是
LIDT m16&32
…你的意思是
LIDT[eax]
?我想用
load\idt()调用C中的函数。
。我必须使用
[eax]
?它不是指向idtr的值而不是它的地址吗?@Tommylee2kI确实计划从C调用汇编例程。虽然我使用的是描述符表的数组而不是指针。这会有什么不同或更好的功能吗?您不应该通过set\u IDT传递IDT by值而不是单个描述符吗?可能我在翻译中遗漏了一些东西,或者应该如何使用这些东西。是的@MichaelPetch,我写错了结构,感谢您指出这一点。如果您想在示例中将desc\t描述为不透明类型(给定
struct desc\t;
)我想您可能需要将
desc_t*表;
更改为
struct desc_t*表;
@aneesharma数组是描述符表的最佳选择。您仍然需要与上面的
struct IDT
等效的属性,因为这正是
lidt
所期望的。我确实计划从C调用汇编例程。尽管我正在使用描述符表的数组不是指针。这会有什么不同或更好的功能吗?你不应该通过值传递IDT而不是通过set_IDT传递单个描述符吗?可能我在翻译中缺少一些东西,或者应该如何使用它。是的@MichaelPetch,我写错了结构,谢谢你的指向如果您想在示例中将desc\t描述为不透明类型(给定
struct desc\t;
)我认为您可能需要将
desc_t*表;
更改为
struct desc_t*表;
@aneesharma数组是描述符表的最佳选择。您仍然需要与上面的
struct IDT
等效的数组,因为这正是
lidt
所期望的。