找回密码
 欢迎注册
楼主: liangbch

[擂台] 求一个无符号整数的10进制位数

[复制链接]
发表于 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 | 显示全部楼层
举个例子


  1. int jmpTable[] = {0, 7, 14}

  2. int JmpTest(void)
  3. {
  4.   __asm
  5.   {
  6.    mov eax, 1
  7.    mov edx, offset jmp1
  8.    mov ecx, [jmpTable + 4]
  9.    add edx, ecx
  10.    jmp edx
  11. jmp1:
  12.    mov ecx, 2
  13.    jmp exit1
  14. jmp2:
  15.    mov ecx, 3
  16.    jmp exit1
  17. jmp3:
  18.    mov ecx, 4
  19.    jmp exit1
  20. exit1:
  21.    mov eax, ecx
  22.   }
  23. }

  24. void main()
  25. {
  26.         int a=JmpTest();
  27.         printf("a=%d",a);

  28. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-2-7 15:00:52 | 显示全部楼层
宝宝的这个题目如果用嵌入汇编,则这么做,
当然可能存在化简, 否则,不如他外部汇编指令少


  1.   //0   9B      0
  2. //1-2  6B   9
  3. //3  9B   15
  4. //4-5 6B   24
  5. //6  9B  30
  6. //7-8  6B   39
  7. //9 12B  45
  8. //10-12 6B  57
  9. //13 12B  63   
  10. //14-15   6B   75  
  11. //16   12B   81
  12. //17-18  6B   93
  13. //19  12B  99   
  14. //20-22 6B   111
  15. //23 12B  117  
  16. //24-25  6B  129  
  17. //26  12B   135
  18. //27-28    6B   147   
  19. //29  12B   151  
  20. //30-31 6B   163
复制代码


  1.   jmpTable[32] = { 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 }
复制代码


  1.   mov ecx, n
  2.   bsr eax, ecx
  3.   mov  edx, offset jmpBegin
  4.   add edx, [jmpTable + eax * 4]
  5.   jmp edx
  6. jmpBegin:
  7. //0   9B
  8.   cmp ecx, 1
  9.   sbb eax, eax
  10.   add eax, 1
  11.   ret
  12. //1-2  6B
  13.   mov eax, 1
  14.   ret
  15. //3  9B
  16.   cmp ecx, 10     //比较的数值小于256,是3B,否则是6B
  17.   sbb eax, eax
  18.   add eax, 2        //加的数值小于256, 是3B,否则是6B
  19.   ret
  20. //4-5 6B
  21.    mov eax, 2     //5B
  22.    ret                    //1B
  23. //6  9B
  24.    cmp ecx, 100
  25.   sbb eax, eax
  26.    add eax, 3
  27.    ret
  28. //7-8  6B
  29.    mov eax, 3
  30.    ret
  31. //9 12B
  32.    cmp ecx, 1000
  33.    sbb eax, eax
  34.    add eax, 4
  35.    ret
  36. //10-12 6B
  37.    mov eax, 4
  38.    ret
  39. //13 12B
  40.    cmp ecx, 10000
  41.    sbb eax, eax
  42.    add eax, 5
  43.    ret  
  44. //14-15   6B
  45.    mov eax, 5
  46.    ret
  47. //16  12B
  48.    cmp ecx, 100000
  49.    sbb eax, eax
  50.    add eax, 6
  51.    ret
  52. //17-18  6B  
  53.    mov eax, 6
  54.    ret
  55. //19  12B
  56.    cmp ecx, 1000000
  57.    sbb eax, eax
  58.    add eax, 7
  59. //20-22 6B
  60.    mov eax, 7
  61.    ret
  62. //23 12B
  63.    cmp ecx, 10000000
  64.    sbb eax, eax
  65.    add eax, 8
  66.    ret
  67. //24-25  6B
  68.    mov eax, 8
  69.    ret
  70. //26  12B
  71.    cmp ecx, 100000000
  72.    sbb eax, eax
  73.    add eax, 9
  74.    ret
  75. //27-28    6B
  76.    mov eax, 9
  77.    ret
  78. //29  12B
  79.    cmp ecx, 1000000000
  80.    sbb eax, eax
  81.    add eax, 10
  82.    ret
  83. //30-31 6B
  84.    mov eax, 10
  85.    ret
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-2-7 15:32:50 | 显示全部楼层
最大执行指令是9条
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-2-7 23:14:29 | 显示全部楼层


  有谁能验证下55#的算法的正确性
  另外,谁能改进它
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-2-8 14:36:50 | 显示全部楼层
19#可以精简为下面的代码
另外,中间10个指令组可以随意排序

  1.    mov edx, n
  2.     xor eax, eax
  3.     cmp edx, 1   //1
  4.     sbb eax, 0
  5.     cmp edx, 10  //2
  6.     sbb eax, 0
  7.     cmp edx, 100 //3
  8.     sbb eax, 0
  9.     cmp edx, 1000 //4
  10.     sbb eax, 0
  11.     cmp edx, 10000 //5
  12.     sbb eax, 0
  13.     cmp edx, 100000 //6
  14.     sbb eax, 0
  15.     cmp edx, 1000000 //7
  16.     sbb eax, 0
  17.     cmp edx, 10000000 //8
  18.     sbb eax, 0
  19.     cmp edx, 100000000 //9
  20.     sbb eax, 0
  21.     cmp edx, 1000000000 //10
  22.     sbb eax, 0
  23.     add eax, 10
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-2-8 21:00:58 | 显示全部楼层
还是太啰嗦了
到底是对x86汇编不精通啊
呵呵
还可以精简,如下

  1.    mov edx, n
  2.     mov eax, 10
  3.     cmp edx, 1000000000 //10
  4.     sbb eax, 0
  5.     cmp edx, 100000000 //9
  6.     sbb eax, 0
  7.     cmp edx, 10000000 //8
  8.     sbb eax, 0
  9.     cmp edx, 1000000 //7
  10.     sbb eax, 0
  11.     cmp edx, 100000 //6
  12.     sbb eax, 0
  13.     cmp edx, 10000 //5
  14.     sbb eax, 0
  15.     cmp edx, 1000 //4
  16.     sbb eax, 0
  17.     cmp edx, 100 //3
  18.     sbb eax, 0
  19.     cmp edx, 10  //2
  20.     sbb eax, 0
  21.     cmp edx, 1   //1
  22.     sbb eax, 0
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-2-8 21:11:09 | 显示全部楼层
先mov eax, 10后,倒序比较更便于理解(当然对CPU无所谓了)。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-4-18 19:37 , Processed in 0.042247 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表