使用 GCC/G++/AS 在固定大小的内存边界上对齐本机代码?

Posted

技术标签:

【中文标题】使用 GCC/G++/AS 在固定大小的内存边界上对齐本机代码?【英文标题】:Align native code on fixed size memory boundaries with GCC/G++/AS? 【发布时间】:2009-07-30 14:45:23 【问题描述】:

我有一个 C 函数,其中包含将实现字节码解释器的字节码的所有代码。

我想知道是否有一种方法可以将内存中的已编译代码段对齐在固定大小的边界上,以便我可以直接计算从字节码值跳转到的地址?有点像数组的工作方式,但不是从计算的地址读取,而是跳到它。

我知道我必须将执行下一次跳转的代码放在每个“字节码代码”段的末尾,并且我必须使边界大小至少与最大段的大小一样大.

如果这是可能的,我将如何告诉编译器/汇编器(gcc / g++ / as)以所述方式对齐?

【问题讨论】:

【参考方案1】:

我意识到这并不是您所要求的,但这是使用 GCC 实现字节码解释器的标准方法。

GCC 的“computed goto”或“labels as values”功能允许您将标签放入数组中并有效地跳转到不同的字节码指令。见Fast interpreter using gcc's computed goto。另请查看这个相关的 Stack Overflow 问题:C/C++ goto 和 GCC documentation on labels as values。

执行此操作的代码如下所示:

void* jumptable[] = &&label1, &&label2;

label:
  /* Code here... */

label2:
  /* Other code here... */

然后您可以使用表格跳转到不同的指令:

goto *jumptable[i];

【讨论】:

【参考方案2】:

这里有两个问题,但答案是一样的。首先,您将(二进制)数据写入(二进制)文件。其次,您正在将该(二进制)数据加载到内存中。你控制它在磁盘上的位置,你控制它在内存中的位置。您可以轻松计算出您要查找的内容。

就个人而言,我可能会在将数据加载到内存时使用一个数组,并且我会确保所有数据都从该数组中的有效索引开始。数组是连续布局的,并且相对容易使用。 Kernighan 和 Ritchie 的书The C Programming Language提到了一种使用unions 进行对齐的技术,但这并没有使指针运算变得更容易。

【讨论】:

【参考方案3】:

如果您使用的是 linux,请使用 posix_memalign()。我相信 Windows 也有类似的功能。

如果您想对齐自己的代码,请查看 gcc __attribute__ 语法。

ld -Ttext 选项也可能有帮助。

【讨论】:

以上是关于使用 GCC/G++/AS 在固定大小的内存边界上对齐本机代码?的主要内容,如果未能解决你的问题,请参考以下文章

Linux 内核源码情景分析 chap 2 存储管理

安卓listview位置怎么调整?为啥调整listView大小时,它上边界永远不动?

为啥 Java 堆的最大大小是固定的?

在共享内存中保持固定大小的符号

ZeroMQ 编译在 Windows 上使用 gcc/g++ 失败

Java NASA Worldwind 多边形与内部边界