表达式计算库
相关的例子:下载>>> 作者:Zoologist 于2008-3-16上传 

                                                         By Zoologist

       话说上回的上回我在网上闲逛中,发现了一个表达式计算的库。这次我就给大家简单的介绍一下。

用法很简单,原型如下:


Evaluate PROC lpExpression:DWORD, lpSymbolCallback:DWORD, dwFlags:DWORD

lpExpression           给出表达式地址,表达式是以0结尾的字符串

lpSymbolCallback  指向一个回调函数,能将表达式中的符号转化为数字。比如:你的

                 表达式为 A+B+C,然后再写一个能讲A赋值为10,B赋值 为20,C赋值为70的函数,

                 写好之后,运行结果就是100.如果此项为0,默认使用十进制。

         详细请看下面的'回调函数说明'

dwFlags 可以包含下面的一个或者多个标志:

EVAL_INTEGER     使用整数进行算术运算
EVAL_FLOAT       使用浮点运算(注意:这个标志会覆盖 EVAL_INTEGER 标志)

EVAL_NO_ARITH    将算术运算作为错误
EVAL_NO_LOGICAL  将逻辑运算作为错误
EVAL_NO_COMPARISON  将比较运算作为错误
EVAL_SPACE_MULTIPLY 将无操作符连接的符号作为乘法处理(默认为出错)
EVAL_IGNORE_FORWARD_REFERENCE               后向引用作为0处理
EVAL_IGNORE_POSITIVE_FORWARD_REFERENCE      忽略可能导致结果变化的前向引用

On return, EDX contains an error code. If this indicates success, ECX:EAX
contain a valid value. If integer evaluation was used, ECX:EAX contains the
64-bit integer result. If floating-point evaluation was used, ECX:EAX
contains a 64-bit floating-point number.
    返回后,EDX 存放着错误代码。如果成功,ECX:EAX存放运算结果。如果指定整数运算,

ECX:EAX会返回64位整数结果。如果指定浮点运算,ECX:EAX 返回64位浮点运算结果。

出错代码:

0 EVAL_ERROR_SUCCESS 无错误

1 EVAL_ERROR_NOT_SUPPORTED   不支持的标志。只有当运算无法进行时才发生。

2 EVAL_ERROR_IN_EXPRESSION  达式包含无效字符或者表达式无法计算。

3 EVAL_ERROR_TOO_COMPLEX    过多的连续操作无法解析。

4 EVAL_ERROR_INVALID_SYMBOL 该函数回调函数返回值无效

5 EVAL_ERROR_OVERFLOW       运算中发生溢出

6 EVAL_ERROR_FORWARD_REFERENCE 发现无效的前向引用

7 EVAL_ERROR_POSITIVE_FORWARD_REFERENCE 发现前向引用,并且忽略之。eax,ecx中的数值是有效的。


*--------------------------*
*  回调函数说明             *
*--------------------------*

SymbolCallback PROC lpSymbol:DWORD, dwFlags:DWORD

lpSymbol 指向一个以0结尾的字符串,包含着找到的符号

dwFlags  内容同传给Evalute的相同

On return, EDX contains a symbol result and ECX:EAX contains the value.

返回结果: EDX 包含符号解析的结果, ECX:EAX 值

符号解析结果:

0 EVAL_SYMBOL_VALID     ECX:EAX 值无效

1 EVAL_SYMBOL_INVALID   符号无效。在Evalate返回之前 eax不会被改变

2 EVAL_SYMBOL_FORWARD_REFERENCE 当前符号无效,但是如果计算标志允许,后面也许会被赋值。


*-----------------*
* 支持的操作      *
*-----------------*

下面是可以支持的运算,简单的介绍和该操作的类型。

注意:对于整数和浮点数,位操作是等价的,布尔预算和比较运算返回值为全1或者全0.

Note that bitwise operators behave identically for integer and floating-
point evaluation, and boolean and comparison operators return all bits
set. Boolean operators treat floating-point numbers as non-zero if they
are normal, denormalised or infinity. NaN and unnormal are treated as zero.

类型: A = 算术运算 L = 逻辑运算 C = 比较运算


+-----+-----+--------------------------------------------+
| Sym | Cat | Behaviour                                                                   |
+-----+-----+--------------------------------------------+
| +   | A   | Addition                                                                           |
+-----+-----+--------------------------------------------+
| -   | A   | Subtraction                                                                     |
+-----+-----+--------------------------------------------+
| *   | A   | Multiplication                                                                |
+-----+-----+--------------------------------------------+
| /   | A   | Division (rounds to nearest for integer)             |
+-----+-----+--------------------------------------------+
| \   | A   | Truncating division                                                     |
+-----+-----+--------------------------------------------+
| %   | A   | Modulus                                                                             |
+-----+-----+--------------------------------------------+
| **   | A  | Exponent                                                                          |
+-----+-----+--------------------------------------------+
| &   | L   | Bitwise-AND                                                                      |
+-----+-----+--------------------------------------------+
| |   | L   | Bitwise-OR                                                                        |
+-----+-----+--------------------------------------------+
| ^   | L   | Bitwise-XOR                                                                      |
+-----+-----+--------------------------------------------+
| &&  | L   | Boolean-AND (treats non-zero as -1)                     |
+-----+-----+--------------------------------------------+
| ||  | L   | Boolean-OR (treats non-zero as -1)                       |
+-----+-----+--------------------------------------------+
| ^^  | L   | Boolean-XOR (treats non-zero as -1)                     |
+-----+-----+--------------------------------------------+
| =   | C   | Is equal to                                                                      |
| ==  | C   |                                                                                             |
| !<> | C   |                                                                                           |
| !>< | C   |                                                                                           |
+-----+-----+--------------------------------------------+
| !=  | C   | Is not equal to                                                            |
| !== | C   |                                                                                           |
| <>  | C   |                                                                                             |
| ><  | C   |                                                                                            |
+-----+-----+--------------------------------------------+
| <   | C   | Is less than                                                                   |
| !>= | C   |                                                                                          |
| !=> | C   |                                                                                          |
+-----+-----+--------------------------------------------+
| <=  | C   | Is less than or equal to                                          |
| =<  | C   |                                                                                            |
| !>  | C   |                                                                                            |
+-----+-----+--------------------------------------------+
| >   | C   | Is greater than                                                             |
| !<= | C   |                                                                                          |
| !=< | C   |                                                                                          |
+-----+-----+--------------------------------------------+
| >=  | C   | Is greater than or equal to                                    |
| =>  | C   |                                                                                            |
| !<  | C   |                                                                                            |
+-----+-----+--------------------------------------------+

   上面的部分翻译的不准确,希望读者自己动手实践一下。

   根据上一期 msfm 的文章,我们不难编写出自己的表达式计算器:

;MASMPlus 代码模板 - 普通的 Windows 程序代码

.386
.Model Flat, StdCall
Option Casemap :None

Include windows.inc
Include user32.inc
Include kernel32.inc
Include gdi32.inc

includelib gdi32.lib
IncludeLib user32.lib
IncludeLib kernel32.lib
include macro.asm

include Expression.inc
includelib Expression.lib

    WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD
   
.DATA
    szClassName db "MASMPlus_Class",0
   
.DATA?
    hInstance    dd ?
    hEdit             dd    ?
    hWnd              dd ?
    lpOldProcEdit dd    ?
.CODE
START:

    invoke GetModuleHandle,NULL
    mov hInstance,eax
    invoke WinMain,hInstance,NULL,NULL,SW_SHOWDEFAULT
    invoke ExitProcess,0
   
Calculate proc hwnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
    LOCAL szBuffer[100]    :BYTE
   
.if uMsg == WM_KEYDOWN
.if wParam == VK_RETURN
invoke GetWindowText,hEdit,addr szBuffer,sizeof szBuffer
invoke Evaluate,addr szBuffer,0,EVAL_INTEGER
invoke wsprintf,addr szBuffer,CTXT("%d"),eax
        invoke SetWindowText,hEdit,addr szBuffer
.endif
.else
invoke CallWindowProc,lpOldProcEdit,hwnd,uMsg,wParam,lParam
.endif
ret
Calculate endp

WinMain proc hInst:DWORD,hPrevInst:DWORD,CmdLine:DWORD,CmdShow:DWORD
    LOCAL wc :WNDCLASSEX
    LOCAL msg :MSG
   
    mov wc.cbSize,sizeof WNDCLASSEX
    mov wc.style,CS_HREDRAW or CS_VREDRAW or CS_BYTEALIGNWINDOW
    mov wc.lpfnWndProc,offset WndProc
    mov wc.cbClsExtra,NULL
    mov wc.cbWndExtra,NULL
    push hInst
    pop wc.hInstance
    mov wc.hbrBackground,COLOR_BTNFACE+1
    mov wc.lpszMenuName,NULL
    mov wc.lpszClassName,offset szClassName
    invoke LoadIcon,hInst,100
    mov wc.hIcon,eax
    invoke LoadCursor,NULL,IDC_ARROW
    mov wc.hCursor,eax
    mov wc.hIconSm,0
    invoke RegisterClassEx, ADDR wc

    invoke CreateWindowEx,
                NULL,
                ADDR szClassName,CTXT("小型计算器"),
                WS_OVERLAPPEDWINDOW,
                85,153,261,74,
                NULL,NULL,hInst,NULL
    mov hWnd,eax

invoke CreateWindowEx,
            WS_EX_STATICEDGE,
    CTEXT("edit"),
    CTEXT("2+3*4"),\
WS_CHILD or WS_VISIBLE,\
8, 9, 236, 21, hWnd, NULL, hInst, NULL
mov hEdit, eax

invoke SetFocus,hEdit
invoke SetWindowLong,hEdit,GWL_WNDPROC,addr Calculate

    mov lpOldProcEdit,eax
   
    invoke ShowWindow,hWnd,SW_SHOWNORMAL
    invoke UpdateWindow,hWnd
   
    StartLoop:
        invoke GetMessage,ADDR msg,NULL,0,0
            cmp eax, 0
            je ExitLoop
                invoke TranslateMessage, ADDR msg
                invoke DispatchMessage, ADDR msg
            jmp StartLoop
    ExitLoop:
   
mov eax,msg.wParam
ret
WinMain endp

WndProc proc hWin:DWORD,uMsg:DWORD,wParam :DWORD,lParam :DWORD
    .if uMsg == WM_DESTROY
        invoke PostQuitMessage,NULL
    .else
        invoke DefWindowProc,hWin,uMsg,wParam,lParam
    .endif
    ret
WndProc endp

END START

    运行结果:

ca.JPG (6120 字节)

    按下回车后会自动计算这个表达式。



<<<上一篇
欢迎访问AoGo汇编小站:http://www.aogosoft.com
下一篇>>>