变体类型在循环中的测试

使用下面的代码进行测试
Dim i As Long, a As Long
Private Sub Command1_Click()
For i = 1 To 10
    a = a + 2
Next i
End Sub

使用SC找到Command1的入口点,OD进行调试,发现循环部分的反汇编是下面的样子
004019CD   > 8BD1           MOV EDX,ECX
004019CF   . 8BC7           MOV EAX,EDI
004019D1   . 83C2 02        ADD EDX,2
004019D4   . 70 3A          JO SHORT TNEXT.00401A10
004019D6   . 83C0 01        ADD EAX,1
004019D9   . 8BCA           MOV ECX,EDX
004019DB   . 70 33          JO SHORT TNEXT.00401A10
004019DD   . 83F8 0A        CMP EAX,0A
004019E0   . 8BF8           MOV EDI,EAX
004019E2   .^7E E9          JLE SHORT TNEXT.004019CD
将上面的代码修改一下
Dim i As Variant, a As Long
Private Sub Command1_Click()
For i = 1 To 10
    a = a + 2
Next i
End Sub
我们把循环计数器i的类型改成了变体,也就是没有Option Explicit强制变量声明情况下使用未声明变量时默认的类型,同样方法看反汇编代码,发现变化是比较大的

00401A78   . FF15 18104000  CALL DWORD PTR DS:[<&MSVBVM60.__vbaVarFo>;  MSVBVM60.__vbaVarForInit
00401A7E   > 3BC3           CMP EAX,EBX
00401A80   . 74 1C          JE SHORT TNEXTWIT.00401A9E
00401A82   . 8B4E 44        MOV ECX,DWORD PTR DS:[ESI+44]
00401A85   . 8D55 9C        LEA EDX,DWORD PTR SS:[EBP-64]
00401A88   . 8D45 AC        LEA EAX,DWORD PTR SS:[EBP-54]
00401A8B   . 83C1 02        ADD ECX,2
00401A8E   . 52             PUSH EDX
00401A8F   . 50             PUSH EAX
00401A90   . 70 47          JO SHORT TNEXTWIT.00401AD9
00401A92   . 57             PUSH EDI
00401A93   . 894E 44        MOV DWORD PTR DS:[ESI+44],ECX
00401A96   . FF15 78104000  CALL DWORD PTR DS:[<&MSVBVM60.__vbaVarFo>;  MSVBVM60.__vbaVarForNext
00401A9C   .^EB E0          JMP SHORT TNEXTWIT.00401A7E
00401A9E   > 895D FC        MOV DWORD PTR SS:[EBP-4],EBX

循环开始调用了MSVBVM60.__vbaVarForInit,而每次循环都要调用MSVBVM60.__vbaVarForNext,大家都知道如此频繁的调用API对于一个循环的执行效率来说是非常不利的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值