liangbch
发表于 2009-2-6 16:20:17
哈哈,学了一招。
不过,你的代码在我的VC6.0有有点问题,首先main函数的定义有问题不能白编译通过,其次将main函数改好后不能运行。稍加修改后,终于能运行了,主要修改是将 "mov edx, jmpTable" 改为 "mov edx, offset jmpTable",.下面是修改后的代码。int JmpTest(void)
{
__asm
{
mov eax, 1
mov edx, offset jmpTable
mov ecx, 4
add edx, ecx
jmp edx
jmpTable:
jmp jmp1
jmp jmp2
jmp jmp3
jmp1:
mov ecx, 2
jmp exit1
jmp2:
mov ecx, 3
jmp exit1
jmp3:
mov ecx, 4
jmp exit1
exit1:
mov eax, ecx
}
}
void main()
{
int a=JmpTest();
printf("a=%d",a);
}
liangbch
发表于 2009-2-6 16:27:16
VC2008, 真正的跳转表, 也可编译,可执行
但现在问题是当前的标号都是短标号(偏移在-128 -- 127内)
所以jmp表指令都是2字节的
不知道,长汇编是否有差异
确实,短的跳转表不太方便,稍微复杂点的程序就不能用了。我将jmp 后加上NEAR关键字,仍然不起作用。
liangbch
发表于 2009-2-6 16:43:49
这种用法相对于在汇编源文件的实现跳表有一个缺点,就是不得不使用2次跳转。无心人能做一个只需要一次跳转指令的实现吗?
gxqcn
发表于 2009-2-6 16:48:53
我喜欢写内嵌汇编,但跳转表还没写过,向你们学习。
无心人
发表于 2009-2-6 17:04:23
呵呵
我一开始是有offset的, 似乎又没有都么关系
因为,错误的把edx写成ebx,结果调试不通过,结果去掉了
如果实现直接jmp,必须预先把jmp地址保存在一个表里
而jmp地址的标号是编译时才确定的
所以是有点困难的
但,似乎我们可以用nop 对齐,使得每个jmp后的代码块一样大小
当然,最好是2,4,8,16,32等大小!!!!
这样子,就不需要预先保存了,只要有第一个地址
下面的可以计算得到
这种方式就需要有能精确测定代码的指令长度的方法了
无心人
发表于 2009-2-6 17:05:23
To: GxQ
这个也是我第一次
无心人
发表于 2009-2-6 17:07:52
另外, jmp的指令是否是短格式,仅和标号的相对偏移有关系
加上也不一定是,不加系统会自动判定
但长格式,不知道有否编译指令能强制是长格式
无心人
发表于 2009-2-6 17:11:14
具体到楼主这个例子
我想能利用8字节指令长度对齐得到C内嵌入汇编的一个代码
mathe
发表于 2009-2-6 18:56:56
vc下要用跳转表还是比较麻烦的.这一点还是gcc比较号,直接可以用c语言写.
无心人
发表于 2009-2-6 21:12:32
:)
肚子讲详细些
不过gcc写汇编麻烦多了