内联汇编寻址方式
Inline assembly addressing mode
我正在尝试使用 -masm=intel 和 32 位 (-m32) 在 gcc 的内联汇编中编写 lidt
指令。所以我定义了以下结构:
typedef struct {
uint16_t length;
uint32_t base;
} idt_desc;
static idt_desc desc = {
sizeof(idt)-1,
(uint32_t)(uintptr_t)idt,
};
如果我使用 nasm,我将不再使用 lidt [desc]
。但是我正在使用内联汇编并将其放在一个函数中:
asm volatile("lidt %0"::"m"(desc):);
这给了我 "Error: unsupported instruction `lidt'"。生成的程序集如下所示:
lidt QWORD PTR desc
据我所知,大括号在 gas intel 语法中是可选的。所以这里的问题是 qword ptr
在 lidt
指令中是不可接受的,因为它需要一个 m16&32
操作数。我怎样才能告诉 gcc 使用它?即,删除 qword ptr
并只使用 desc
。
您需要打包 idt_desc
结构,因为编译器将在 16 位 length
和 32 位 base
结构成员之间添加填充。即使编译器设法为此生成代码,该结构也会无效,并且 LIDT 几乎肯定会加载错误的 IDT 记录,导致最终在运行时出现 crash/triple 错误。应该是:
typedef struct {
uint16_t length;
uint32_t base;
} __attribute__((packed)) idt_desc;
-masm=intel
选项似乎导致编译器将结构的解压缩版本视为填充的 8 字节结构,然后将其视为 64 位 QWORD
。在 32 位代码中,LIDT
不接受指向 QWORD
的指针,它接受指向 48 位值(在某些 Intel 方言中又名 FWORD
)的指针,这是源代码的错误。通过打包结构,编译器不再生成 QWORD
,因为打包版本的大小为 6 个字节。
我正在尝试使用 -masm=intel 和 32 位 (-m32) 在 gcc 的内联汇编中编写 lidt
指令。所以我定义了以下结构:
typedef struct {
uint16_t length;
uint32_t base;
} idt_desc;
static idt_desc desc = {
sizeof(idt)-1,
(uint32_t)(uintptr_t)idt,
};
如果我使用 nasm,我将不再使用 lidt [desc]
。但是我正在使用内联汇编并将其放在一个函数中:
asm volatile("lidt %0"::"m"(desc):);
这给了我 "Error: unsupported instruction `lidt'"。生成的程序集如下所示:
lidt QWORD PTR desc
据我所知,大括号在 gas intel 语法中是可选的。所以这里的问题是 qword ptr
在 lidt
指令中是不可接受的,因为它需要一个 m16&32
操作数。我怎样才能告诉 gcc 使用它?即,删除 qword ptr
并只使用 desc
。
您需要打包 idt_desc
结构,因为编译器将在 16 位 length
和 32 位 base
结构成员之间添加填充。即使编译器设法为此生成代码,该结构也会无效,并且 LIDT 几乎肯定会加载错误的 IDT 记录,导致最终在运行时出现 crash/triple 错误。应该是:
typedef struct {
uint16_t length;
uint32_t base;
} __attribute__((packed)) idt_desc;
-masm=intel
选项似乎导致编译器将结构的解压缩版本视为填充的 8 字节结构,然后将其视为 64 位 QWORD
。在 32 位代码中,LIDT
不接受指向 QWORD
的指针,它接受指向 48 位值(在某些 Intel 方言中又名 FWORD
)的指针,这是源代码的错误。通过打包结构,编译器不再生成 QWORD
,因为打包版本的大小为 6 个字节。