mathe
发表于 2009-2-6 21:52:20
gcc里面可以将跳转的目标直接放置在数组里面,然后用goto语句跳转过去:
http://nathanxu.blog.51cto.com/50836/56661
无心人
发表于 2009-2-6 22:12:19
?
怎么看不到回复
呵呵, 再来一次
我刚转了mathe提供的那个链接
无心人
发表于 2009-2-7 14:03:38
昨天想了一晚上
连做梦也是在紧张的(不是编程序)抗洪抢险(好多人,大院子,污水,很多,淘水)
似乎可以把代码段的相对偏移保存到数组
此时的跳转表,只要获得起始地址
加上相对偏移
就能跳转了
这么做,可保证跳转正确,且不需刻意保持代码的字节数
缺点是,需要仔细计算代码的字节数
有错误就会产生错误的跳转甚至是跳转到指令的中间
造成非法指令
无心人
发表于 2009-2-7 14:11:30
举个例子
int jmpTable[] = {0, 7, 14}
int JmpTest(void)
{
__asm
{
mov eax, 1
mov edx, offset jmp1
mov ecx,
add edx, ecx
jmp edx
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);
}
无心人
发表于 2009-2-7 15:00:52
宝宝的这个题目如果用嵌入汇编,则这么做,
当然可能存在化简, 否则,不如他外部汇编指令少
//0 9B 0
//1-26B 9
//39B 15
//4-5 6B 24
//69B30
//7-86B 39
//9 12B45
//10-12 6B57
//13 12B63
//14-15 6B 75
//16 12B 81
//17-186B 93
//1912B99
//20-22 6B 111
//23 12B117
//24-256B129
//2612B 135
//27-28 6B 147
//2912B 151
//30-31 6B 163
jmpTable = { 0, 9, 9, 15, 24, 24, 30, 39, 39, 45, 57, 57, 57, 63, 75, 75, 81, 93, 93, 99, 111, 111, 111, 117, 129, 129, 135, 147, 147, 151, 163, 163 }
mov ecx, n
bsr eax, ecx
movedx, offset jmpBegin
add edx,
jmp edx
jmpBegin:
//0 9B
cmp ecx, 1
sbb eax, eax
add eax, 1
ret
//1-26B
mov eax, 1
ret
//39B
cmp ecx, 10 //比较的数值小于256,是3B,否则是6B
sbb eax, eax
add eax, 2 //加的数值小于256, 是3B,否则是6B
ret
//4-5 6B
mov eax, 2 //5B
ret //1B
//69B
cmp ecx, 100
sbb eax, eax
add eax, 3
ret
//7-86B
mov eax, 3
ret
//9 12B
cmp ecx, 1000
sbb eax, eax
add eax, 4
ret
//10-12 6B
mov eax, 4
ret
//13 12B
cmp ecx, 10000
sbb eax, eax
add eax, 5
ret
//14-15 6B
mov eax, 5
ret
//1612B
cmp ecx, 100000
sbb eax, eax
add eax, 6
ret
//17-186B
mov eax, 6
ret
//1912B
cmp ecx, 1000000
sbb eax, eax
add eax, 7
//20-22 6B
mov eax, 7
ret
//23 12B
cmp ecx, 10000000
sbb eax, eax
add eax, 8
ret
//24-256B
mov eax, 8
ret
//2612B
cmp ecx, 100000000
sbb eax, eax
add eax, 9
ret
//27-28 6B
mov eax, 9
ret
//2912B
cmp ecx, 1000000000
sbb eax, eax
add eax, 10
ret
//30-31 6B
mov eax, 10
ret
无心人
发表于 2009-2-7 15:32:50
最大执行指令是9条
无心人
发表于 2009-2-7 23:14:29
:)
有谁能验证下55#的算法的正确性
另外,谁能改进它
无心人
发表于 2009-2-8 14:36:50
19#可以精简为下面的代码
另外,中间10个指令组可以随意排序
mov edx, n
xor eax, eax
cmp edx, 1 //1
sbb eax, 0
cmp edx, 10//2
sbb eax, 0
cmp edx, 100 //3
sbb eax, 0
cmp edx, 1000 //4
sbb eax, 0
cmp edx, 10000 //5
sbb eax, 0
cmp edx, 100000 //6
sbb eax, 0
cmp edx, 1000000 //7
sbb eax, 0
cmp edx, 10000000 //8
sbb eax, 0
cmp edx, 100000000 //9
sbb eax, 0
cmp edx, 1000000000 //10
sbb eax, 0
add eax, 10
无心人
发表于 2009-2-8 21:00:58
还是太啰嗦了
到底是对x86汇编不精通啊
呵呵
还可以精简,如下
mov edx, n
mov eax, 10
cmp edx, 1000000000 //10
sbb eax, 0
cmp edx, 100000000 //9
sbb eax, 0
cmp edx, 10000000 //8
sbb eax, 0
cmp edx, 1000000 //7
sbb eax, 0
cmp edx, 100000 //6
sbb eax, 0
cmp edx, 10000 //5
sbb eax, 0
cmp edx, 1000 //4
sbb eax, 0
cmp edx, 100 //3
sbb eax, 0
cmp edx, 10//2
sbb eax, 0
cmp edx, 1 //1
sbb eax, 0
gxqcn
发表于 2009-2-8 21:11:09
先mov eax, 10后,倒序比较更便于理解(当然对CPU无所谓了)。