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
所期望的。