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无所谓了)。
页: 1 2 3 4 5 [6] 7
查看完整版本: 求一个无符号整数的10进制位数