我有一个 C 函数,其中包含将实现字节码解释器的字节码的所有代码。
我想知道是否有一种方法可以在固定大小的边界上对齐内存中的已编译代码段,以便我可以直接计算从字节码值跳转到的地址?排序与数组的工作方式相同,但不是从计算的地址读取,而是跳到它。
我知道我必须将执行下一次跳转的代码放在每个“字节码代码”段的末尾,并且我必须使边界大小至少与最大段的大小一样大。
如果这甚至可能,我将如何告诉编译器/汇编器(gcc / g++ / as)以所述方式对齐?
我有一个 C 函数,其中包含将实现字节码解释器的字节码的所有代码。
我想知道是否有一种方法可以在固定大小的边界上对齐内存中的已编译代码段,以便我可以直接计算从字节码值跳转到的地址?排序与数组的工作方式相同,但不是从计算的地址读取,而是跳到它。
我知道我必须将执行下一次跳转的代码放在每个“字节码代码”段的末尾,并且我必须使边界大小至少与最大段的大小一样大。
如果这甚至可能,我将如何告诉编译器/汇编器(gcc / g++ / as)以所述方式对齐?
我意识到这并不是您所要求的,但这是使用 GCC 实现字节码解释器的标准方法。
GCC 的“computed goto”或“labels as values”功能允许您将标签放入数组中并有效地跳转到不同的字节码指令。请参阅使用 gcc 的计算 goto 的快速解释器。另请查看相关的 Stack Overflow 问题:C/C++ goto和关于标签的 GCC 文档作为值。
执行此操作的代码如下所示:
void* jumptable[] = {&&label1, &&label2};
label:
/* Code here... */
label2:
/* Other code here... */
然后,您可以使用该表跳转到不同的指令:
goto *jumptable[i];
这里有两个问题,但答案是一样的。首先,您将(二进制)数据写入(二进制)文件。其次,您正在将该(二进制)数据加载到内存中。你控制它在磁盘上的位置,你控制它在内存中的位置。您可以轻松计算出您要查找的内容。
就个人而言,我可能会在将数据加载到内存时使用数组,并且我会确保所有数据都从该数组中的有效索引开始。数组是连续布局的,并且相对容易使用。Kernighan 和 Ritchie 的书The C Programming Language提到了一种使用union
s 进行对齐的技术,但这并没有使指针算术变得更容易。
如果您使用的是 linux,请使用 posix_memalign()。我确信 Windows 也有类似的功能。
如果您想对齐自己的代码,请查看 gcc__attribute__
语法。
ld -Ttext 选项也可能会有所帮助。