什么是callx86机器代码中绝对指针的"正确"方法?有没有一种方法可以在一条指令中完成它?
我想做什么:
我正在尝试基于"子程序线程"构建一种简化的迷你JIT(仍然).它基本上是字节码解释器中最短的步骤:每个操作码都是作为一个单独的函数实现的,因此每个基本的字节码块都可以"JIT"到它自己的新程序中,如下所示:
{prologue}
call {opcode procedure 1}
call {opcode procedure 2}
call {opcode procedure 3}
...etc
{epilogue}
Run Code Online (Sandbox Code Playgroud)
因此,我们的想法是每个块的实际机器代码只能从模板中粘贴(根据需要扩展中间部分),并且需要"动态"处理的唯一位是将每个操作码的函数指针复制到正确的位置作为每个调用指令的一部分.
我遇到的问题是了解call ...模板部分的用途.x86似乎没有考虑到这种用法,并且有利于相对和间接调用.
它看起来像我可以使用FF 15 EFBEADDE或2E FF 15 EFBEADDE在假设调用函数DEADBEEF(通过把东西变成一个汇编和反汇编,看到什么产生有效的结果,基本上发现了这些未通过了解他们在做什么),但我不理解的东东细分,特权和相关信息足以看出差异,或者这些信息与更常见的call指令有何不同.英特尔架构手册还建议这些仅在32位模式下有效,在64位模式下"无效".
有人可以解释这些操作码以及我是如何或者是否会为此目的使用它们或其他人?
(通过寄存器使用间接调用也有明显的答案,但这似乎是"错误的"方法 - 假设实际存在直接调用指令.)