嘿,我想知道是否有人可以帮助我使用C中的头等标签。
我目前正在尝试从内存中读取java字节码(AVR设备的FLASH内存),我想将每条指令视为标签,并使用goto语句调度该指令并跳转到适当的标签。
但问题是我用来从内存中读取指令的函数返回一个无符号字节。
u08_t nvmfile_read08(void *addr) {
u08_t val;
addr = NVMFILE_ADDR(addr); // remove marker (if present)
memcpy_P((u08_t*)&val, (PGM_P)addr, sizeof(val));
return val;
}
instr = nvmfile_read08(pc);
所以我的问题是如何将instr转换成类似的东西:
void *ptr;
ptr = &&instr;
goto *ptr;
然后这段代码将理想地跳转到这个标签:(假设iload是最后读取的指令)
iload:
// Execute the iload jvm instruction.
由于
答案 0 :(得分:2)
有两种方法:switch
语句或函数指针数组。
switch
的案例可以由枚举器命名,如下所示:
enum jvm_opcodes {
push = 0,
pop = 1,
/* etc */
blah = 254
};
然后开关看起来像这样:
switch ( instr ) {
case push: {
} break;
case pop: {
} break;
}
函数指针数组将直接发送到其他函数而不会写出switch
。如果源代码分布在更多文件上,可能会更方便。
/* dispatch.c */
typedef void (*jvm_dispatch)(); /* function pointer type */
jvm_dispatch insn_dispatch_table[] = { /* define array */
handle_push, /* opcode 0 */
handle_pop, /* opcode 1 */
/* etc */
};
insn_dispatch_table[ insn ](); /* call an entry from the array */
/* push.c */
void handle_push() {
}
/* pop.c */
void handle_pop() {
}