找回密码
 欢迎注册
楼主: 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-11-24 08:24 , Processed in 0.023100 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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