返回列表 发新帖

[意见反馈] 关于“Smali 指令查询”功能的疑问

[复制链接]

43

主题

453

回帖

2654

积分

大学生

Rank: 5Rank: 5

金币
54
好评
51
信誉
102
发表在  2026-1-28 22:24:07 来自手机  | 显示全部楼层 | 阅读模式  来自 广西
本帖最后由 善始繁_克终寡 于 2026-1-28 22:24 编辑

指令查询功能中的部分指令的描述对我来说好像存在一些的误导,指令主要是 cmpl 这一类的

cmpl-float vAA, vBB, vCC
比较两个单精度浮点数:
vAA = vBB < vCC ? 是:1,否:-1,相等:0

这类指令中的这个小于号 < 给了我误导,它会让我以为,如果 vBB 小于 vCC ,则 vAA 是 1,但我通过查看一些资料和测试之后才发现不是这样的

参考资料:
https://bbs.kanxue.com/thread-194252-1.htm
仔细过了一遍 dalvik 指令,这两条指令实际上一样,区别只是倾向于先比较小于还先比较大于
参考这里 http://androidxref.com/8.0.0_r4/xref/art/runtime/interpreter/interpreter_switch_impl.cc#657
-----
https://bbs.kanxue.com/thread-195920-1.htm
-----
https://android.googlesource.com/platform/art/+/refs/heads/main/runtime/interpreter/interpreter_switch_impl-inl.h#469

https://android.googlesource.com/platform/art/+/refs/heads/main/runtime/interpreter/interpreter_switch_impl-inl.h#484
-----
https://source.android.com/docs/core/runtime/dalvik-bytecode?hl=en#instructions

好像是说,只要 vBB > vCC,则 vAA 是 1;vBB < vCC,则 vAA 为 -1;相等,vAA 则为 0

测试代码如下:
  1. .method private testBranch(DD)Ljava/lang/String;
  2.     .registers 6

  3.     cmpl-double v0, p1, p3
  4.     # vBB
  5.     invoke-static {p1, p2}, Lmt/Log418FB2;->b1(D)V
  6.     # vCC
  7.     invoke-static {p3, p4}, Lmt/Log418FB2;->b2(D)V
  8.     # vAA
  9.     invoke-static {v0}, Lmt/Log418FB2;->b1(I)V

  10.     if-nez v0, :cond_16

  11.     const-string v0, "0"

  12.     invoke-static {v0}, Lmt/Log418FB2;->b1(Ljava/lang/Object;)V
  13.     # 返回值:0
  14.     invoke-static {}, Lmt/Log418FB2;->b()V

  15.     return-object v0

  16.     :cond_16
  17.     cmpl-double v0, p1, p3
  18.     # vBB_1
  19.     invoke-static {p1, p2}, Lmt/Log418FB2;->b3(D)V
  20.     # vCC_1
  21.     invoke-static {p3, p4}, Lmt/Log418FB2;->b4(D)V
  22.     # vAA_1
  23.     invoke-static {v0}, Lmt/Log418FB2;->b2(I)V

  24.     if-lez v0, :cond_2c

  25.     const-string v0, "1"

  26.     invoke-static {v0}, Lmt/Log418FB2;->b1(Ljava/lang/Object;)V
  27.     # 返回值:1
  28.     invoke-static {}, Lmt/Log418FB2;->b()V

  29.     return-object v0

  30.     :cond_2c
  31.     const-string v0, "-1"

  32.     invoke-static {v0}, Lmt/Log418FB2;->b1(Ljava/lang/Object;)V
  33.     # 返回值:-1
  34.     invoke-static {}, Lmt/Log418FB2;->b()V

  35.     return-object v0
  36. .end method
复制代码


cmpl-double 的日志如下
  1. --------------------
  2. cmpl-double vBB: NaN
  3. cmpl-double vCC: 1.0
  4. cmpl-double vAA: -1

  5. :cond_16
  6. cmpl-double vBB_1: NaN
  7. cmpl-double vCC_1: 1.0
  8. cmpl-double vAA_1: -1

  9. 返回值: -1
  10. --------------------
  11. cmpl-double 指令的 vBB, vCC 分别为 NaN, 1.0。vAA 为 -1

  12. --------------------
  13. cmpl-double vBB: NaN
  14. cmpl-double vCC: 2.0
  15. cmpl-double vAA: -1

  16. :cond_16
  17. cmpl-double vBB_1: NaN
  18. cmpl-double vCC_1: 2.0
  19. cmpl-double vAA_1: -1

  20. 返回值: -1
  21. --------------------
  22. cmpl-double 指令的 vBB, vCC 分别为 NaN, 2.0。vAA 为 -1

  23. --------------------
  24. cmpl-double vBB: NaN
  25. cmpl-double vCC: NaN
  26. cmpl-double vAA: -1

  27. :cond_16
  28. cmpl-double vBB_1: NaN
  29. cmpl-double vCC_1: NaN
  30. cmpl-double vAA_1: -1

  31. 返回值: -1
  32. --------------------
  33. cmpl-double 指令的 vBB, vCC 分别为 NaN, NaN。vAA 为 -1

  34. --------------------
  35. cmpl-double vBB: 1.0
  36. cmpl-double vCC: 2.0
  37. cmpl-double vAA: -1

  38. cmpl-double vBB_1: 1.0
  39. cmpl-double vCC_1: 2.0
  40. cmpl-double vAA_1: -1

  41. 返回值: -1
  42. --------------------
  43. cmpl-double 指令的 vBB, vCC 分别为 1.0, 2.0。vAA 为 -1

  44. --------------------
  45. cmpl-double vBB: 1.0
  46. cmpl-double vCC: NaN
  47. cmpl-double vAA: -1

  48. cmpl-double vBB_1: 1.0
  49. cmpl-double vCC_1: NaN
  50. cmpl-double vAA_1: -1

  51. 返回值: -1
  52. --------------------
  53. cmpl-double 指令的 vBB, vCC 分别为 1.0, NaN。vAA 为 -1

  54. --------------------
  55. cmpl-double vBB: 1.0
  56. cmpl-double vCC: 1.0
  57. cmpl-double vAA: 0
  58. 返回值: 0
  59. --------------------
  60. cmpl-double 指令的 vBB, vCC 分别为 1.0, 1.0。vAA 为 0

  61. --------------------
  62. cmpl-double vBB: 2.0
  63. cmpl-double vCC: NaN
  64. cmpl-double vAA: -1

  65. cmpl-double vBB_1: 2.0
  66. cmpl-double vCC_1: NaN
  67. cmpl-double vAA_1: -1

  68. 返回值: -1
  69. --------------------
  70. cmpl-double 指令的 vBB, vCC 分别为 2.0, NaN。vAA 为 -1

  71. --------------------
  72. cmpl-double vBB: 2.0
  73. cmpl-double vCC: 1.0
  74. cmpl-double vAA: 1

  75. cmpl-double vBB_1: 2.0
  76. cmpl-double vCC_1: 1.0
  77. cmpl-double vAA_1: 1

  78. 返回值: 1
  79. --------------------
  80. cmpl-double 指令的 vBB, vCC 分别为 2.0, 1.0。vAA 为 1

  81. --------------------
  82. cmpl-double vBB: 2.0
  83. cmpl-double vCC: 2.0
  84. cmpl-double vAA: 0
  85. 返回值: 0
  86. --------------------
  87. cmpl-double 指令的 vBB, vCC 分别为 2.0, 2.0。vAA 为 0
复制代码

当 vBB < vCC 时,即比如分别为 1.0 和 2.0 时,vAA 的值是 -1,而不是 1

cmpg-double 的日志

  1. --------------------
  2. cmpg-double vBB: NaN
  3. cmpg-double vCC: 1.0
  4. cmpg-double vAA: 1

  5. :cond_16
  6. cmpg-double vBB_1: NaN
  7. cmpg-double vCC_1: 1.0
  8. cmpg-double vAA_1: 1

  9. 返回值: 1
  10. --------------------
  11. cmpg-double 指令的 vBB, vCC 分别为 NaN, 1.0。vAA 为 1

  12. --------------------
  13. cmpg-double vBB: NaN
  14. cmpg-double vCC: 2.0
  15. cmpg-double vAA: 1

  16. :cond_16
  17. cmpg-double vBB_1: NaN
  18. cmpg-double vCC_1: 2.0
  19. cmpg-double vAA_1: 1

  20. 返回值: 1
  21. --------------------
  22. cmpg-double 指令的 vBB, vCC 分别为 NaN, 2.0。vAA 为 1

  23. --------------------
  24. cmpg-double vBB: NaN
  25. cmpg-double vCC: NaN
  26. cmpg-double vAA: 1

  27. :cond_16
  28. cmpg-double vBB_1: NaN
  29. cmpg-double vCC_1: NaN
  30. cmpg-double vAA_1: 1

  31. 返回值: 1
  32. --------------------
  33. cmpg-double 指令的 vBB, vCC 分别为 NaN, NaN。vAA 为 1

  34. --------------------
  35. cmpg-double vBB: 1.0
  36. cmpg-double vCC: 2.0
  37. cmpg-double vAA: -1

  38. cmpg-double vBB_1: 1.0
  39. cmpg-double vCC_1: 2.0
  40. cmpg-double vAA_1: -1

  41. 返回值: -1
  42. --------------------
  43. cmpg-double 指令的 vBB, vCC 分别为 1.0, 2.0。vAA 为 -1

  44. --------------------
  45. cmpg-double vBB: 1.0
  46. cmpg-double vCC: NaN
  47. cmpg-double vAA: 1

  48. cmpg-double vBB_1: 1.0
  49. cmpg-double vCC_1: NaN
  50. cmpg-double vAA_1: 1

  51. 返回值: 1
  52. --------------------
  53. cmpg-double 指令的 vBB, vCC 分别为 1.0, NaN。vAA 为 1

  54. --------------------
  55. cmpg-double vBB: 1.0
  56. cmpg-double vCC: 1.0
  57. cmpg-double vAA: 0
  58. 返回值: 0
  59. --------------------
  60. cmpg-double 指令的 vBB, vCC 分别为 1.0, 1.0。vAA 为 0

  61. --------------------
  62. cmpg-double vBB: 2.0
  63. cmpg-double vCC: NaN
  64. cmpg-double vAA: 1

  65. cmpg-double vBB_1: 2.0
  66. cmpg-double vCC_1: NaN
  67. cmpg-double vAA_1: 1

  68. 返回值: 1
  69. --------------------
  70. cmpg-double 指令的 vBB, vCC 分别为 2.0, NaN。vAA 为 1

  71. --------------------
  72. cmpg-double vBB: 2.0
  73. cmpg-double vCC: 1.0
  74. cmpg-double vAA: 1

  75. cmpg-double vBB_1: 2.0
  76. cmpg-double vCC_1: 1.0
  77. cmpg-double vAA_1: 1

  78. 返回值: 1
  79. --------------------
  80. cmpg-double 指令的 vBB, vCC 分别为 2.0, 1.0。vAA 为 1

  81. --------------------
  82. cmpg-double vBB: 2.0
  83. cmpg-double vCC: 2.0
  84. cmpg-double vAA: 0
  85. 返回值: 0
  86. --------------------
  87. cmpg-double 指令的 vBB, vCC 分别为 2.0, 2.0。vAA 为 0
复制代码


如果我的结论没错的话,我觉得可以把相关指令的错误描述修改成正确的描述
已有2人评分好评 金币 理由
Bin + 5 + 50 很给力!
青春向上 + 1 太细节了。[赞]

查看全部评分 总评分:好评 +5  金币 +51 

回复

使用道具 举报

319

主题

4374

回帖

4万

积分

管理员

Rank: 9Rank: 9Rank: 9

金币
121011
好评
1132
信誉
201

MT论坛元老MT论坛优秀教师2018MT论坛优秀成员

QQ
发表于 2026-2-3 15:28:04 | 显示全部楼层  来自 福建
查了下确实如此,很少用这个指令,之前写的时候看到cmpl和cmpg有点想当然地以为后面的l和g表示less than和greater than的缩写

比较逻辑
该指令比较 vBB 和 vCC 中的浮点数值,结果存入 vAA:

条件        结果 (vAA)
vBB > vCC        1
vBB == vCC        0
vBB < vCC        -1
任一操作数为 NaN        -1

cmpl-float vs cmpg-float 的区别
Dalvik 有两个浮点比较指令,它们的唯一区别在于处理 NaN(Not a Number) 时的行为:

指令        NaN 时的结果
cmpl-float        -1 (less bias)
cmpg-float        1 (greater bias)
cmpl = compare less(NaN 偏向小)
cmpg = compare greater(NaN 偏向大)
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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