Tra*_*boi 6 c c++ gcc goto jump-table
我正在制作某种解释器,并且由于本地标签地址,我正在计算一个静态常量跳转表。
你知道演习,
static const int JUMP_TABLE[] = { &&case0 - &&case0, &&case1 - &&case0等等。
出于各种原因,主要是性能,我想在初始化期间在对象中复制/压缩此表。
我的头撞在墙上,因为我不知道如何逃避函数的词汇范围!
我怎样才能以某种方式从另一个函数引用 &&case0 ?
有人对此有什么好技巧吗?
提前致谢
我不知道在纯 GNU C 中实现此目的的方法,因此下面的方法使用其他机制。
您可以编译目标文件两次,在第一次运行时收集偏移量并在第二次运行时使用它们。例如
int foo(int x) {
#ifdef GENERATE_ADDRESSES
static __attribute__((section(".foo_offsets"))) unsigned offsets[] = { &&case0 - &&case0, &&case1 - &&case0 };
#endif
switch (x) {
case0:
case 0:
return 1;
case1:
case 1:
return 2;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
现在您可以编译,从.foo_offsets部分中提取字节并在第二次运行时将它们嵌入到您的应用程序中
$ gcc tmp.c -c -DGENERATE_ADDRESSES
$ objcopy -j .foo_offsets -O binary tmp.o
$ xxd -i tmp.o | tee offsets.inc
unsigned char tmp_o[] = {
0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00
};
unsigned int tmp_o_len = 8;
Run Code Online (Sandbox Code Playgroud)
您可以使用内联汇编来全球化标签:
extern char foo_case0[];
extern char foo_case1[];
const void *foo_addresses[] = { &foo_case0[0], &foo_case1[0] };
int foo(int x) {
switch (x) {
case 0:
asm("foo_case0:");
return 1;
case 1:
asm("foo_case1:");
return 2;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,在这种情况下,您只能收集地址(而不是偏移量),因此您需要在启动时手动计算偏移量。
| 归档时间: |
|
| 查看次数: |
160 次 |
| 最近记录: |