接口函数
PA 中有许多接口函数,可以供我们直接调用,特别方便,但是得先了解各个参数和功能,现在把它们总结在这里,方便以后查阅
以下将guest客户地址写做虚拟地址,将host地址写做实际地址。
地址转换
guest_to_host(p)
将一个 uint32_t 类型的虚拟地址转换为 void * 的实际地址
host_to_guest(p)
与上一个相反
I/O 相关
uint32_t vaddr_read(vaddr_t, int);
从虚拟地址 vaddr_t 出读取 int 字节的数据,最多为四个字节。
uint32_t paddr_read(paddr_t, int);
和上一个没什么区别。。可能以后会改吧。
void vaddr_write(vaddr_t, int, uint32_t);
将 int 字节的数据 uint32_t 写入虚拟地址 vaddr_t,
void paddr_write(paddr_t, int, uint32_t);
同上。。
ModRM 相关
void operand_write(Operand , rtlreg_t );
将右边指针指向的数据 写入 左边的操作数(reg or mem)
译码相关
make_DHelper(XXX);
宏展开:decode_xxx 函数
make_EHelper(XXX);
宏展开:exec_xxx 函数
make_DopHelper(XXX);
宏展开:decode_op_xxx 函数
前缀
make_EHelper(operand_size);
操作数前缀,转为 16 位操作数
static make_EHelper(2byte_esc);
双字节指令前缀
杂项
make_group(name, …);
group 类型,需要进一步解析 ModRM 的 reg/opcode 字节 来确定真正的指令
make_EHelper(real);
读取操作码,操作码写入 decoding.opcode,操作数宽度写入 src(dest, src1).width,然后执行 opcode_table 中的 译码函数 和 解码函数
IDEXW(id, ex, w);
将要用到的,译码函数 decode_id, 执行函数 exec_ex,操作数宽度 w
idex(vaddr_t eip, opcode_entry e);
解码(instr decode)和执行(execute)
i386 手册: 地址
参考手册: 地址
推荐通过附录A中的 opcode_map 和 opcode_table 了解指令