📄 表达式计算库.txt
字号:
表达式计算库
相关的例子:下载>>> 作者: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
运行结果:
按下回车后会自动计算这个表达式。
--------------------------------------------------------------------------------
<<<上一篇 欢迎访问AoGo汇编小站:http://www.aogosoft.com/ 下一篇>>>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -