在C中使用x86风格的跳转表
我正试图在C中像这样做一个跳转表在C中使用x86风格的跳转表,c,assembly,x86,jump-table,C,Assembly,X86,Jump Table,我正试图在C中像这样做一个跳转表 cmp eax, dword 3 ;max number ja invalid ;default jmp [eax*4+jumptable] ;jump to handler invalid: retn jumptable: dd handle0, handle1, handle2, hand
cmp eax, dword 3 ;max number
ja invalid ;default
jmp [eax*4+jumptable] ;jump to handler
invalid:
retn
jumptable:
dd handle0, handle1, handle2, handle3
handle0:
....
诸如此类
我是从这个开始的
void dohandler(int a, int b, void (*jumptable[4]) (int x))
if (a > 3) return
else jumptable[3 * 4](b);
}
int main() {
void (*jumptable[4]) (int x);
jumptable[0] = &handler1;
... etc
dohandler(1,2,jumptable);
}
void handler1(int x) { ... }
.. etc
但是它工作不好。
jumptable
是一个指针数组。不要尝试缩放偏移量,只索引要引用的指针
void dohandler(int a, int b, void (*jumptable[4]) (int x))
if (a >= 0 && a < 4)
jumptable[a](b);
}
void-dohandler(inta、intb、void(*jumptable[4])(intx))
如果(a>=0&&a<4)
可跳表[a](b);
}
不确定,但我认为您在这里有几个问题:
void dohandler(int a, int b, void (*jumptable[4]) (int x))
if (a > 3) return
else jumptable[3 * 4](b);
}
首先,在引用跳转表时不使用a
,我认为这对应于汇编版本中的eax
寄存器。第二,不要把它乘以4。我认为这是指针的大小,数组引用为您提供了这一功能。所以你最终会得到这样的结果:
void dohandler(int a, int b, void (*jumptable[4]) (int x))
if (a > 3) return
else jumptable[a](b);
}
开关
将被编译成一个jumptable,只要标签值不是太稀疏即可。表达式使用小尺寸类型(如unsigned char
)或屏蔽高位可能会有所帮助,因此编译器不会在跳转表跳转之前添加额外的“if in range”条件,但这可能并不重要
最重要的是,实验。使用
gcc-S
检查程序集输出。switch语句对您做了什么?您应该决定是用C还是用ASM编程,然后这样做。switch。。没有我在这个项目上需要的那么灵活比如,300个case的switch语句并不理想。我会使用switch,但我有300多个case,它们的顺序从0到299。编译器是否无法为该switch生成一个跳转表?似乎大多数编译器在这个愿望上都有点古怪,有一个标志可以用来强制它并接受“结果”如果有的话,它试图避免。