标题:溢出,怎么解决?
只看楼主
yuma
Rank: 11Rank: 11Rank: 11Rank: 11
来 自:银河系
等 级:贵宾
威 望:33
帖 子:1883
专家分:2904
注 册:2009-12-22
结帖率:89.13%
 问题点数:0 回复次数:3 
溢出,怎么解决?
debug.print 361375661375661 Mod 1
搜索更多相关主题的帖子: print debug 溢出 
2022-12-17 16:01
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4912
专家分:29900
注 册:2008-10-15
得分:0 
见鬼了
测试结果是 mod 运算产生的溢出,
需要 参看反汇编,目前只知道是 给出的立即数在 double 范围内,
改数据类型为 Decimal 也报溢出,真是见鬼。

回家看反汇编去 。。。。。


授人于鱼,不如授人于渔
早已停用QQ了
2022-12-18 10:36
William1949
Rank: 3Rank: 3
等 级:新手上路
威 望:8
帖 子:109
专家分:0
注 册:2009-3-17
得分:0 
dim  i as currency
i= 361375661375661
debug.print i - 1 * int(i / 1)
2022-12-18 11:56
风吹过b
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:364
帖 子:4912
专家分:29900
注 册:2008-10-15
得分:0 
;Print 361375661375661# Mod 1
;FLD src  装入实数到st(0)
004019E3    DD05 80104000   fld     qword ptr [401080]               ;ds:[00401080]=361375661375661.0
004019E9    83C4 0C         add     esp, 0C                          ;+OC,MSVBVM60.__vbaFpI4需要临时变量空间
004019EC    FF15 64104000   call    [<&MSVBVM60.__vbaFpI4>]          ; MSVBVM60.__vbaFpI4
004019F2    6A 00           push    0
004019F4    56              push    esi
004019F5    68 B8144000     push    004014B8
004019FA    FFD7            call    edi                              ; 调用显示命令
;竟然没有计算过程................



; MSVBVM60.__vbaFpI4,好像只负责取整,好吧
4FFA6C70 >  D9FC            frndint                                  ;保存实数st(0)到dest
4FFA6C72    83EC 0C         sub     esp, 0C                          ;这里减了0C,恢复到栈指针
4FFA6C75    DB1424          fist    dword ptr [esp]                  ;舍入到整数
4FFA6C78    DF7C24 04       fistp   qword ptr [esp+4]                ;然后再执行一次出栈操作,跳了4字节
4FFA6C7C    DFE0            fstsw   ax                               ;保存状态字的值到AX
4FFA6C7E    A8 0D           test    al, 0D                           ;测试是否超栈顶,会写状态位
4FFA6C80    0F85 40B30000   jnz     4FFB1FC6                         ;上步检测到错误,这里应该是溢出,没跟踪
4FFA6C86    58              pop     eax
4FFA6C87    83C4 08         add     esp, 8                            ;其余8字节。用于防止数据超栈顶导致错误
4FFA6C8A    C3              retn


;那就再来一段 Print 361375661375661# Mod 3
004019E3    DD05 80104000   fld     qword ptr [401080]           
004019E9    83C4 0C         add     esp, 0C
004019EC    FF15 64104000   call    [<&MSVBVM60.__vbaFpI4>]          ; MSVBVM60.__vbaFpI4
004019F2    99              cdq                                      ; 扩展EAX寄存器为EDX:EAX,64位,为除法做准备
004019F3    B9 03000000     mov     ecx, 3                           ; MOD 3 的 3,用的是 32位寄存器
004019F8    F7F9            idiv    ecx                              ; edx:eax 除以 ecx。
;如果参数是 r8/m8,   将把 AX      做被除数; 商 -> AL,  余数 -> AH
;如果参数是 r16/m16, 将把 DX:AX   做被除数; 商 -> AX,  余数 -> DX
;如果参数是 r32/m32, 将把 EDX:EAX 做被除数; 商 -> EAX, 余数 -> EDX
004019FA    52              push    edx                              ; 调用显示命令


到这里,真相大白了,需要使用 idiv 有符号整数除法时 , 就一定会换算成整数,这个处理过程在 __vbaFpI4 (浮点转整数4字节)函数中处理
然而这个 __vbaFpI4 函数中使用 4字节来保存数据 [esp+4] ,如果超了 LONG范围(-2,147,483,648 到 2,147,483,647),自然而然的就报溢了错误了。
经测试 ,mod  和 \ 会报这个错误,猜测就是会调用 idiv 指令。

好奇怪, / 竟然不报错。。。。继续看
;'Print 361375661375661# / 3
004019D3    DD05 80104000   fld     qword ptr [401080]          ;同样,装入数据
004019D9    833D 00204000 0>cmp     dword ptr [402000], 0       ;以及下一句,检测错误用的
004019E0    75 08           jnz     short 004019EA
004019E2    DC35 78104000   fdiv    qword ptr [401078]          ;调用浮点除,[401078]=3,好吧服了


以用反汇编使用 OllyICE看的
工程:
窗体上拉一个命令命令,双击后然后输入以下二条命令
 
Print "HYHYHY"                '用于反汇编里定位指令位置
Print 361375661375661# / 3    '这行命令根据需要修改

--------------------
解决办法:自己整大数 除法去吧。


[此贴子已经被作者于2022-12-19 20:33编辑过]


授人于鱼,不如授人于渔
早已停用QQ了
2022-12-19 20:23



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-510977-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.202235 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved