³o¤@½g¤å³¹¡A±N¤¶²Ð¦p¦ó¥Î²Õ¦X»y¨¥¹ê§@¤@Ópºâ¾÷µ{¦¡¡ACALC.EXE¡A¥¦¥i¥HÅý¨Ï¥ÎªÌ¿é¤J¼Æ¦r ( ºÙ¬°¹Bºâ¤¸¡Aoperand ) ¥H¤Î¡u¡Ï¡v¡B¡u¡Ð¡v¡B¡u¡Ñ¡v¡B¡u / ¡v¡B¡u x^y ¡v(«ü¼Æ)¡B¡u ( ¡v¡B¡u ) ¡v¡B¡ulog¡vµ¥¹Bºâ¤l ( operator )¡Aµ{¦¡·|¨Ì·Ó¥ý¼°£¡B«á¥[´îªº¦¸§Ç°µ¹Bºâ¡A¦A§âµª®×¦L¦b¿Ã¹õ¤W¡Cµe±¦p¤U¹Ï¡A¥ªÃ䪺¹Ï¬O¿é¤J¹Bºâ¦¡¡A¥kÃ䪺¹Ï¬O«ö¤U¡uEXE¡v«ö¶s«áªºµ²ªG¡G

¤@¯ë¦b¤p¾Ç®É¡A§Ú̩ҾǪº¹Bºâ¦¡³£¬O¡u¤¤§Ç¹Bºâ¦¡¡v¡A¤°»ò¬O¤¤§Ç¹Bºâ¦¡©O¡H´N¬O¹Bºâ¤l¦b¹Bºâ¤¸¤¤¶¡ªº¼Æ¾Ç¹Bºâ¦¡¡A¨Ò¦p¡G
5*4 33+66 (22+5)*4
³£ºÙ¬°¤¤§Ç¹Bºâ¦¡¡C¦b¤¤§Ç¹Bºâ¦¡ùتº¹Bºâ¤l¦³Àu¥ý¦¸§Ç¡A¨Ã¤£¬O¥ý¹J¨ìªº¹Bºâ¤l¥ý¦æ¹Bºâ¡A¤j®a³£ª¾¹D¥²¶·¨Ì·Ó¥ý¼°£¡B«á¥[´îªº³W«h°µ¹Bºâ¡A°²¦p¦³¬A¸¹ªº¸Ü¡A¬A¸¹ªºÀu¥ý§ÇÁÙ¤ñ¼°£ªk¨Ó±o¤j¡AÀ³¥ý¹Bºâ¡A¨Ò¦p¡G
(22+5)*4
´N±o¥ýºâ 22+5¡A¤£¥i¥ýºâ¼ªk¡C°²¦p¹Bºâ¦¡¤¤¥]§t¤F¨ç¼Æ ( ¥]§t«ü¼Æ¡B¹ï¼Æ¡B¤T¨¤¨ç¼Æµ¥µ¥ )¡A¨Ò¦p
3+10*log 2¡×3+10*0.301
¨º»ò³o¨Ç¨ç¼ÆªºÀu¥ý¦¸§Ç¤S¤j©ó¼°£¡C´«¥y¸Ü»¡¡A§ÚÌ¥i¥H¾ã²z±o¨ì¹ï©ó¤¤§Ç¹Bºâ¦¡ªºÀu¥ý¦¸§Ç¬O
¬A¸¹¡Ö¨ç¼Æ¡Ö¼°£¡Ö¥[´î
«á§Ç¹Bºâ¦¡¬OªiÄõ¼Æ¾Ç®a¾|¥dÁºû©_ ( Jan Łukasiewicz ) ©Òµo©úªº¡A³oºØ¹Bºâ¦¡¬O§â¹Bºâ¤¸¼g¦b«e±¡A¦Ó¹Bºâ¤l¼g¦b«á±¡A¨Ò¦p 2+5 ¼g¦¨ 2 5 +¡C«á§Ç¹Bºâ¦¡¨S¦³¡u(¡v¡B¡u)¡v¡A¹ï©ó¦b¹q¸£¤W°µ¥|«h¹Bºâ¡A«Ü¦³À°§U¡C§Ṳ́w¸g«Ü²ßºD¤¤§Çªí¥Üªk¡A¼g¦¨«á§Çªí¥Üªk«Ü¤£®e©ö²z¸Ñ¡A©³¤U¬O§â¤¤§Ç¹Bºâ¦¡§ï¦¨«á§Ç¹Bºâ¦¡ªº¨BÆJ¡G
¨Ò¦pn§â 2+5*6-4*8 Åܦ¨«á§Ç¦¡¡A¨Ì¾Ú¤W±ªºì«h¡A¦Ó¦³©³¤U¨BÆJ¡G
ÁöµM±`¥Îªº¹Bºâ¤l¡A¦p¡G¥[¡B´î¡B¼¡B°£»Ýn¦³¨âÓ¹Bºâ¤¸¤~¥i¹Bºâ¡F¦ý¬O¤]¦³¤@¨Ç¹Bºâ¤l¥u»Ý¤@Ó¹Bºâ¤¸´N¥i¹Bºâ¤F¡A¨Ò¦pt¸¹¡B¹ï¼Æ ( log )¡B¤T¨¤¨ç¼Æµ¥¡C¦pªG¹Bºâ¦¡¤¤¦³³o¨Ç¹Bºâ¤l¡A·Qn§â¥¦Åܦ¨«á§Ç¹Bºâ¦¡¡A¤èªk¤]¹³¤W±¬Û¦ü¡A¥u¤£¹Lª½±µ§â¥Î¹Bºâ¤l¨ú¥N¡u ) ¡v¡A¤]¥i»¡¬Oª½±µ§â¹Bºâ¤l½Õ¨ì¹Bºâ¤¸¤§«á¡C¨Ò¦p§â 2+5*LOG 3 §ï¦¨«á§Ç¹Bºâ¦¡¡A¨BÆJ¦p¤U¡G
¤W±¬O¤HÃþ¥H¤j¸£§â¤¤§Ç¦¡§ï¦¨«á§Ç¦¡ªº¹Lµ{¡A¦b²Õ¦X»y¨¥¹Bºâ¤¤¡An§â¤¤§Ç¦¡§ï¦¨«á§Ç¦¡¡A¶··Ç³Æ¤@Ó°ïÅ|¡A³oÓ°ïÅ|¨Ã¤£¬O«e±©Ò´£¨ìªº¥Î PUSH¡BPOP «O¦s¼ÆÈ©Î©I¥s°Æµ{¦¡®É©Ò¥Îªº¡A¥H ESP ¬°«ü¼Ðªº¤@¶ô°O¾ÐÅé¡C³oùØ©ÒÁ¿ªº°ïÅ|¡A¨ä¹ê¬O¤@ӥѳ\¦h¦¨û©Ò²Õ¦¨ªº°}¦C¡A¨Ã¥B¥Î¤@ÓÅܼƫü¦V³oÓ°}¦C¦ì§}¡A¨C·í¦³¸ê®Æn¦s¤J¦¹°}¦C®É¡A¥u¯à¦s¦b³oÓÅܼƩҫü¦ì§}¡A¦s§¹¤§«á¡AÅܼƷ|«ü¦V¤U¤@Ó°}¦Cªº¦ì§}¡C·ín±q°}¦C¨ú¥X¸ê®Æ®É¡A¤]¥²¶·¥Ñ³oÓÅܼƩҫüªº¦ì§}¨ú¥X¨Ó¡A¤£¯à¸g¥Ñ¨ä¥L¤è¦¡¨ú¥X¡A¸ê®Æ¨ú¥X«á¡AÅܼƫh·|«ü¦V°ïÅ|ªº«e¤@¦ì§}¡C¦Ü©ó§â¸ê®Æ±À¤J³oÓ°ïÅ|«á¡AÅܼƫü¦V¸û°ª¦ì§}ÁÙ¬O«ü¦V¸û§C¦ì§}¡A«h¬OµL©Ò¿×¡A³o¤@ÂI©M PUSH¡BPOP ¦s¨úªº°ïÅ|¤]¤£¦P¡C¦ý¬O¦]¬°³oºØ°}¦C¨ã¦³¡u¥ý¶i«á¥X¡vªº¯S©Ê¡A©Ò¥H¤~ºÙ¦¹°}¦C¬°°ïÅ|¡C
¦b¹ê§@¤W¡An§â¤¤§Ç¹Bºâ¦¡Âà´«¦¨«á§Ç¹Bºâ¦¡¡A¥i¥H§Q¥Î°ïÅ|¡C¦b³o¤@³¹¨Ò¤lùØ¡A¤p¤ì°¸·Ç³Æ¤F¤@Ó¦r¦ê¡A°µ¬°Àx¦s«á§Ç¹Bºâ¦¡¡A¤]·Ç³Æ¤F¤@Ó°ïÅ|°µ¬°¦bÂà´«¹Lµ{¤¤Àx¦s¹Bºâ¤l¤§¥Î¡A©Î³\¥i¥HºÙ¦¹°ïÅ|¬°¹Bºâ¤l°ïÅ|¡C¾ãÓÂà´«¦¨«á§Ç¹Bºâ¦¡ªº¹Lµ{¦p¤U¡G
ÁöµM«á§Ç¹Bºâ¦¡¤£©ö²z¸Ñ¡A¦ý¬O¥¦¦³¨âÓ¦n³B¡C¤@¬O¨S¦³¬A¸¹¡A¤G¬O²Å¦Xpºâ¾÷¹B§@¤è¦¡¡C³o¨â¥y¸Üªº·N«ä¬O¨Ï¥Î«á§Ç¹Bºâ¦¡®É¡A¤£»Ýn¦Ò¼{¹Bºâ¤lªºÀu¥ý§Ç¡C°²¦p§Ṳ́w¸g¨Ì·Ó¤Wz¤èªk§â¤¤§Ç¹Bºâ¦¡Âà´«¦¨«á§Ç¹Bºâ¦¡¥H«á¡Anpºâµ²ªG¡A´N«Ü²³æ¤F¡C³o®É¥u»Ýn·Ç³Æ¤@Ó°ïÅ|¡A³oÓ°ïÅ|¥Î¨Ó¦s©ñ¹Bºâ¤¸¡AºÙ¬°¹Bºâ¤¸°ïÅ|¡Cpºâ®É¡A§â«á§Ç¹Bºâ¦¡°²·Q¦¨¤@Ó¦r¦ê¡A¥Ñ¦¹¦r¦êªº¥ªÃä¦V¥k¶}©lpºâ¡A¨C¦¸¨ú¥X¤@Ó¹Bºâ¤¸©Î¹Bºâ¤l¡A·í¹J¨ì¹Bºâ¤¸®É¡Aª½±µ§â¹Bºâ¤¸±À¤J¹Bºâ¤¸°ïÅ|¡F·í¹J¨ì¹Bºâ¤l®É¡A«hµø¦¹¹Bºâ¤l»Ýn´XÓ¹Bºâ¤¸¡A¦Û¹Bºâ¤¸°ïÅ|¨ú¥X²Å¦X¸Ó¹Bºâ¤¸©Ò»Ý¹Bºâ¤¸ªºÓ¼Æ¡A¦A»P¹Bºâ¤lpºâ¡AµM«á¦A§âµ²ªG±À¤J¹Bºâ¤¸°ïÅ|¡C¦p¦¹¤@ª½«½Æ³oÓ¨BÆJ¡Aª½¨ì«á§Ç¦¡¦r¦ê¤w¸gªÅ¤F¡A³o®É¦b¹Bºâ¤¸°ïÅ|ªº¼ÆÈ´N¬O³Ì«áªºµ²ªG¡C
©³¤U¬O²Õ¦X»y¨¥ì©l½X¡ACALC.ASM¡G
;¨ã¦³¥ý¼°£«á¥[´îªºpºâ¾÷µ{¦¡
page ,132
.386
.model flat,stdcall
option casemap:none
DlgProc proto :DWORD,:DWORD,:DWORD,:DWORD
include windows.inc
include user32.inc
include kernel32.inc
include masm32.inc
includelib user32.lib
includelib kernel32.lib
includelib masm32.lib
IDE_EXPRESSION equ 1000
IDB_CLEAR equ 1001
IDB_EXECUTE equ 1002
IDM_EXIT equ 3000
IDM_CLEAR equ 3001
IDM_PI equ 3002
IDM_EULER equ 3003
CD_LEN equ 100 ;³Ì¦h¿é¤J100Ó¤º½X
;*********************************************************************
.const
dwTen WORD 10
DlgName BYTE 'CalcDlg',0
CalcIcon BYTE 'CalcIco',0
;parse table (x,y)=(²{¦bªº,«e¤@Óªº)
; 10 L
; ¾ËO «ü
; N + - * / ( ) - ¤è¼ÆG ¼Æ=
; 0 1 2 3 4 5 6 7 8 9 A B C
parse_table BYTE 0,1,1,1,1,0,1,0,1,1,0,1,1 ;0 N
BYTE 1,0,0,0,0,1,0,1,1,0,1,0,0 ;1 +
BYTE 1,0,0,0,0,1,0,1,1,0,1,0,0 ;2 -
BYTE 1,0,0,0,0,1,0,1,1,0,1,0,0 ;3 *
BYTE 1,0,0,0,0,1,0,1,1,0,1,0,0 ;4 /
BYTE 1,0,0,0,0,1,0,1,1,0,1,0,0 ;5 (
BYTE 0,1,1,1,1,0,0,0,0,1,0,1,1 ;6 )
BYTE 1,1,1,1,1,1,0,2,1,0,1,0,0 ;7 -(t¸¹)
BYTE 1,0,0,0,0,1,0,1,0,0,1,0,0 ;8 10¾¤è
BYTE 0,1,1,1,1,0,1,0,0,1,0,0,1 ;9 x^(-1)˼Æ(R)
BYTE 1,0,0,0,0,1,0,1,1,0,1,0,0 ;A LOG
BYTE 1,0,0,0,0,1,0,1,1,0,1,0,0 ;B x^y«ü¼Æ
BYTE 1,0,0,0,0,1,0,1,1,0,1,0,1 ;C =
;Åã¥Ü©óIDE_EXPRESSION½s¿è®Ø¤ºªº¨ç¼Æ¤å¦r
stReciprocal BYTE 6,'^(-1) ' ;˼ơA^(-1) ·|Åã¥Ü©ó½s¿è®Ø¤º¡C6ªí¥Ü¦@¦³6Ó¦r¤¸
stLOG BYTE 3,'LOG' ;¹ï¼Æ¡ALOG·|Åã¥Ü©ó½s¿è®Ø¤º¡C3ªí¥Ü¦@¦³3Ó¦r¤¸
stExponent BYTE 3,'x^y'
;N + - * / ( ) - E R L ^ =
icp BYTE 0,2,2,3,3,5,4,5,5,5,5,5,0 ;¹Bºâ¦¡Àu¥ý§Ç
isp BYTE 0,2,2,3,3,1,4,4,4,4,4,4,0 ;°ïÅ|Àu¥ý§Ç
display_table BYTE '+','-','*','/','(',')','-','E'
action DWORD number,plus,minus,multiple,divide,0,0,negative
DWORD exp10,reciprocal,log,exponent,answer
szErrorMsg0 BYTE 'Syntax Error',0
szErrorMsg1 BYTE 'Invalid Number',0
szPi BYTE '3.14159265358979324',0 ;¶ê©P²v
szEuler BYTE '2.71828182845904524',0 ;¤×©Ô¼Æ
;*********************************************************************
.data
hInstance HINSTANCE ?
CommandLine LPSTR ?
hwndEdit HWND ?
;szExpression¦s©ñ¨Ï¥ÎªÌ¿é¤Jªº¦r¦ê¡A¦¹¦r¦ê¥Ñ³B²z«ö¶s¦Ó±o¡A¨Ò¦p¨Ï¥ÎªÌ¨Ì¦¸«ö¤U
;«ö¶s7¡B«ö¶s¡Ï¡B«ö¶sLOG¡B«ö¶s2¡B«ö¶s0¡B«ö¶sEXE¡A«hszExpression·|Åܦ¨ 37 2B 4C 4F 47 32 30
;¥ç§Y7+LOG20¡C¦ÓstCodeBuffer«h¬O¦s©ñ¦U«ö¶s¤§¤º½X¡A¥H¤W¨Ò«hÅܦ¨ 07 11 1A 02 00
szExpression BYTE CD_LEN*2 dup (0) ;¹Bºâ¦¡ªºASCII½X¦s©ñ³B
stCodeBuffer BYTE CD_LEN dup (0ffh) ;¹Bºâ¦¡¤º½X¦s©ñ³B
;ptExpression¡BptCodeBuffer«h¬OszExpression¡BstCodeBuffer¤§«ü¼Ð¡A¦]¬°«ö¶sªº¦r¦ê
;¤£¤@©wµ¥ªø¡A¨Ò¦p˼Ʀ³6Ó¦r¡u^(-1) ¡v¡A¹ï¼Æ¦³3Ó¦r¡uLOG¡v
ptExpression LPSTR ?
ptCodeBuffer LPSTR ?
previous_code BYTE ? ;«e¤@Ó¤º½X
current_code BYTE ? ;·í«e¤º½X
lpPostfix LPSTR ? ;«á§Ç¹Bºâ¦¡¦r¦êªº«ü¼Ð
lpOpStack LPSTR ? ;¹Bºâ¤l°ïÅ|«ü¼Ð
lpNumTemp LPSTR ?
lpNumStack LPSTR ? ;¹Bºâ¤¸°ïÅ|«ü¼Ð
stPostfix BYTE CD_LEN dup (0) ;«á§Ç¦¡¦r¦ê
aryOpStack BYTE CD_LEN dup (0) ;¹Bºâ¤l°ïÅ|
aryNumStack TBYTE CD_LEN/2 dup (0);¹Bºâ¤¸°ïÅ|
aryNumTemp TBYTE CD_LEN/2 dup (0);¼È®É¦s©ñ¹Bºâì³B
dwNum WORD ?
szAnswer BYTE 20 dup (0)
;Y«ö¤U¡uEXE¡v«ö¶s«á¡A©|¥¼«ö¤U¨ä¥L«ö¶s«e¡AbIfExecute¬°1
bIfExecute BYTE 0
;*********************************************************************
.code
;---------------------------------------------------------------------
;ªì©l¤ÆszExpression¡BstCodeBuffer¨â¦r¦ê¤Î¨ä«ü¼Ð¡A½s¿è®Ø³]¬°ªÅ¦r¦ê¡AbIfExecute³]¬°¹s
Initiation proc uses eax ecx edi,hwnd:HWND
cld
sub eax,eax
mov edi,offset szExpression
mov ecx,CD_LEN/2
mov bIfExecute,al
rep stosd
dec eax
mov edi,offset stCodeBuffer
mov ecx,CD_LEN/4
rep stosd
invoke SetDlgItemText,hwnd,IDE_EXPRESSION,offset szExpression
mov ptExpression,offset szExpression
mov ptCodeBuffer,offset stCodeBuffer
ret
Initiation endp
;---------------------------------------------------------------------
;¨D2 X(¨D2ªºX¦¸¤è)
;¿é¤J¡GST¡ÐX
;¿é¥X¡GST¡Ð2^X
two_p_x proc
local fpu_cw:word
fstcw fpu_cw ;¨ú±o±±¨î¦r²Õ
fwait ;µ¥«ÝCPUÀx¦s§¹²¦
mov ax,fpu_cw ;«O¦sì±±¨î¦r²Õ
and fpu_cw,0f3ffh ;¨Ï±±¨î¦r²ÕÅܦ¨¦VtµL¤j±Ë¤J¡A±ý¹F¦¹¥Ø
or fpu_cw,00400h ;ªº¥²¶·¨Ï±±¨î¦r²Õ²Ä10¡B11¦ì¤¸Åܬ° 01
fldcw fpu_cw ;¸ü¤J·sªº±±¨î¦r²Õ
fld st ; x ; x ; ;
frndint ;i=int x; x ; ;¦VtµL¤j±Ë¤J
mov fpu_cw,ax ;¨ú¦^ªº±±¨î¦r²Õ
fldcw fpu_cw ; i ; x ; ;¸ü¤Jªº±±¨î¦r²Õ
fsub st(1),st ; i ; f=x-i ; ;ST(1)¬°¤p¼Æ³¡¤À¡Af
fxch ; f ; i ; ;¥æ´«
f2xm1 ; 2f-1 ; i ; ;¨D 2 ªº¤p¼Æ³¡¤À¦¸¤è
fld1 ; 1 ; 2f-1 ; i ;¸ü¤J 1
faddp st(1),st ; 2f ; i ; ;§¹¦¨ 2 ªº¤p¼Æ³¡¤À¦¸¤è
fscale ; 2x ; i ; ;¨Ï 2
fstp st(1) ; 2x ; ; ;¥h±¼¾ã¼Æ³¡¤À
ret ;ªð¦^¥Dµ{¦¡
two_p_x endp
;---------------------------------------------------------------------
;pºâ X^Y ¤§È
;ì²z¡GX^Y=2^(log2 X^Y)=2^(Y*log2 X) ¦¹³Blog2 Xªí¥Ü¥H2¬°©³¡AX¤§¹ï¼Æ
;¿é¤J¡GST - ©³¼Æ¡AX
; ST1- «ü¼Æ¡AY
;¿é¥X¡GY¿ù»~(¹sªº¹s¦¸¤è©Î©³¼Æ¬°tÈ)¡A«h¶i¦ìºX¼Ð³Q³]©w¡F
; Y¨S¿ù»~¡A«h¶i¦ìºX¼Ð³Q²M°£¡A¥BST¬°X^Y
x_p_y proc
local fpu_sw:word
ftst
fstsw fpu_sw
fwait
mov ax,fpu_sw ;§âª¬ºA¦r²Õ²¾¤JAX
sahf ;§âª¬ºA¦r²Õªº°ª¦ì¤¸³¡¥÷²¾¤JºX¼Ð
jz zero_base ;©³¼Æ¬°0
jc err1 ;--st0--;--st1--;YCY¡Aªí¥Ü©³¼Æ¬°t¼Æ
; X ; Y
fyl2x ;Ylog2 X;
call two_p_x ; X^Y ;
jmp ok
zero_base:
fcomp ;©³¼Æ¬°¹s¡A¼u¥X©³¼Æ¡AµM«á¦A
ftst ;Àˬd«ü¼Æ¬O§_¬°¹s
fstsw fpu_sw
mov ax,fpu_sw
sahf
jz err2 ;Y¬°ZR¡Aªí¥Ü«ü¼Æ¤]¬°¹s
fcomp
fldz ;©³¼Æ¬°¹s¡A«ü¼Æ¤£¬°¹s¡A¨äµª®×¬°¹s¤£¶·pºâ
ok: clc
jmp exit
err1: fcomp
err2: fcomp
stc
exit: ret
x_p_y endp
;---------------------------------------------------------------------
;¦bstCodeBuffer¤¤¡A¥HptCodeBuffer©Ò«ü¦ì§}¬D¥X¤@ÓTOKEN¡C
;¦ó¿×TOKEN©O¡H¨Ò¦p·ístCodeBuffer¬° 07 11 1A 02 00¡Aªí¥Ü¨Ï¥ÎªÌ¿é¤J7+LOG20¡A
;¦¹®É¦@¦³4ÓTOKEN¡A¤À§O¬O7¡B+¡BLOG¡B20¡Cª`·N¡I¤@Ó§¹¾ãªº¼ÆÈ¬O¤@ÓTOKEN¡A
;¦]¦¹20¥uºâ¤@ÓTOKEN¡A¤£¬O¨âÓTOKEN
GetToken proc
local ifPoint:BYTE ;¼ÆÈ¬O§_¥X²{¤p¼Æ
mov edx,ptCodeBuffer
mov ifPoint,0 ;¥ý°²³]¨S¦³¤p¼ÆÂI
gt0: cmp byte ptr [edx],0ffh
je gt5
;ÀˬdTOKEN¬O§_¬°¼ÆÈ¡AY¬°¼ÆÈ¡A¸õ¦Ügt1
cmp byte ptr [edx],0bh
jb gt1
;¦¹TOKEN¬°¹Bºâ¤l
mov al,[edx]
sub al,10h
inc edx
mov current_code,al
cmp al,2 ;YAL=2¡Aªí¥Ü¦¹¹Bºâ¤l¬°¡u-¡v
jne gt5
;Àˬd¡u-¡v¬Ot¸¹©ÎªÌ´î¸¹¡A¦pªG¡u-¡v¦b¡u)¡v¤§«á©ÎªÌ¡u-¡v¥X²{©ó
;¼Æ¦r¤§«á¡A¬°´î¸¹¡F§_«h¡u-¡v¬°t¸¹
cmp previous_code,6 ;«e¤@¹Bºâ¤l¬°¼Æ¦r©Î¡u)¡v¡Aªí¥Ü
je gt5 ;¦¹TOKEN¬°´î¸¹
cmp previous_code,0
je gt5
mov current_code,7 ;¦¹TOKEN¬°t¸¹
jmp gt5
;¦¹TOKEN¬°¼ÆÈ(¹Bºâ¤¸)
gt1: mov current_code,0 ;--st0--;--st1--;--st2--;
fldz ; i=0 ; ;
gt2: mov al,[edx]
inc edx
cbw
mov dwNum,ax
cmp al,0ah ;YAL¬°¤p¼ÆÂI
je gt3
cmp ifPoint,0 ;Àˬd¬O§_´¿¥X²{¹L¤p¼ÆÂI¡AY´¿
jne gt4 ;¸g«h¸õ¦Ügt4¡FY§_«hÄ~Äò°õ¦æ
fimul dwTen ; i=10i ; ;
fiadd dwNum ; i=i+AL; ;
cmp byte ptr [edx],0bh
jb gt2
jmp short gt5
gt3: inc ifPoint
cmp ifPoint,1 ;YifPoint¶W¹L1¡Aªí¥Ü¿é¤J¨âÓ¤p¼ÆÂI
ja gt6
fldz ; 0 ; i ;
fld1 ; 1 ; 0 ; i ;
fidiv dwTen ; t=0.1 ; f=0 ; i ;
jmp gt2
gt4: fld st(0) ; t ; t ; f ; i ;
fimul dwNum ; f*t ; t ; f ; i ;
faddp st(2),st ; t ;f=f*t+f; i ;
fidiv dwTen ; t=t/10; f ; i
cmp byte ptr [edx],0bh
jb gt2
fcomp st(0) ; f ; i ;
faddp st(1),st ; n=f+i ;
gt5: mov ptCodeBuffer,edx
clc
jmp gt7
gt6: stc
gt7: ret
GetToken endp
;---------------------------------------------------------------------
Execute proc uses esi edi
local fpu_sw:word
finit
mov ptCodeBuffer,offset stCodeBuffer
mov lpPostfix,offset stPostfix
mov lpNumTemp,offset aryNumTemp
;§â¡u=¡v¹Bºâ¤l¦s©óaryOpStack¡A·í¨ú¥X¡u=¡v¹Bºâ¤l®Éªí¥Ü³Ì«á¤@Ó¹Bºâ¤l
mov lpOpStack,offset aryOpStack
mov al,0ch
mov edx,lpOpStack
mov byte ptr [edx],al
inc lpOpStack
mov current_code,al ;³]©wcurrent_code¬°¡u=¡v¹Bºâ¤l
;¨ú¥X¤@ÓTOKEN¡AYCYªí¥Ü¿é¤J¦³°ÝÃD¡CYNCªí¥Ü¨S°ÝÃD¡AY¦¹TOKEN¬°¼ÆÈ¡A«h¸Ó¼ÆÈ
;¦s©óST(0)¡Acurrent_code¬°0¡FY¦¹TOKEN¬°¹Bºâ¤l¡A«hcurrent_code¬°¹Bºâ¤l¤§¤º½X¡C
get_tk: mov al,current_code
mov previous_code,al
call GetToken
jnc @f
mov edx,offset szErrorMsg1
jmp complete
;Àˬd¹Bºâ¤l¤§»yªk¬O§_¥¿½T¡AÀˬd¤èªk¬O«Ø¥ßparse_table¡A¥H·í«e¤º½X»P«e¤@¤º½X¬d
;¾\¦¹ªí®æ¡C¦pªG¬°1¡Aªí¥Ü»yªk¥¿½T¡FY¬°0ªí¥Ü»yªk¿ù»~¡C
@@: movzx eax,previous_code ;pºâEDX=previous_code*13+current_code
mov cx,0dh
mul cx
movzx edx,current_code
add edx,eax
mov cl,parse_table[edx] ;CL=0ªí»yªk¿ù»~¡ACL=1ªí»yªk¥¿½T
mov al,current_code
or cl,cl
jnz syntax_correct
syntax_error:
mov edx,offset szErrorMsg0
error: stc
jmp complete
;»yªk¥¿½T¡A¶}©l§â¤¤§Ç¹Bºâ¦¡Âà´«¦¨«á§Ç¹Bºâ¦¡¡C
syntax_correct:
mov edi,lpPostfix
cmp al,0 ;YAL=0¡Aªí¥ÜTOKEN¬°¹Bºâ¤¸
jnz not_number
mov [edi],al ;¦b«á§Ç¦¡¦r¦ê¿é¥X¹Bºâ¤¸¤§¤º½X¡A0
inc lpPostfix
mov edx,lpNumTemp
fstp tbyte ptr [edx] ;¦Ó¯u¥¿ªº¹Bºâ¤¸¦s©ñ¦baryNumTemp°}¦CùØ
add lpNumTemp,10 ;«ü¦VaryNumTemp°}¦Cªº¤U¤@Ó¦¨û
jmp get_tk
not_number:
cmp al,6 ;ÀˬdTOKEN¬O§_¬°¡u)¡v
jne other_op_code
r_par0: mov esi,lpOpStack ;YTOKEN¬°¡u)¡v¡A«h¨ú¥X¹Bºâ¤l°ïÅ|¤¤ªº¹Bºâ¤l
r_par1: mov al,[esi-1] ;¦s¤J«á§Ç¹Bºâ¦¡¦r¦ê¡Aª½¨ì¹J¨ì¡u(¡v¬°¤î
cmp al,0ch ;Àˬd¹Bºâ¤l°ïÅ|¬O§_¤w¸g¨S¦³¹Bºâ¤l¤F
je syntax_error ;¡A¦pªG¨S¹Bºâ¤l¡Aªí¥Ü¡u)¡v¤ñ¡u(¡v¦h
dec esi
cmp al,5 ;¹J¨ì¡u(¡v¡Aµ²§ô¨ú¥X¹Bºâ¤lªº°Ê§@
je r_par2
stosb
jmp r_par1
r_par2: mov lpOpStack,esi
mov lpPostfix,edi
jmp get_tk
other_op_code:
movzx edx,al
mov cl,icp[edx] ;CL=·í«eTOKENªºICP
mov esi,lpOpStack
dec esi
movzx edx,byte ptr[esi]
mov ch,isp[edx] ;CH=¹Bºâ¤l°ïÅ|³»ªºISP
cmp cl,ch
jbe pop_op_code
;Y·í«e¹Bºâ¤lªºICP¡Ö¹Bºâ¤l°ïÅ|³»ªºISP¡A«h§â·í«e¹Bºâ¤l±À¤J°ïÅ|
push_op_code:
mov al,current_code
mov edx,lpOpStack
mov [edx],al
inc lpOpStack
jmp get_tk
;Y·í«e¹Bºâ¤lªºICP¡Ø¹Bºâ¤l°ïÅ|³»ªºISP¡A«h¼u¥X¹Bºâ¤l°ïÅ|³»
pop_op_code:
mov esi,lpOpStack
sub edx,edx
mov al,[esi-1] ;¨ú¥X¹Bºâ¤l°ïÅ|³»¤§¹Bºâ¤l
stosb ;¿é¥X¨ì«á§Ç¦¡¦r¦ê
dec esi ;³]©w·sªº°ïÅ|³»
mov dl,[esi-1] ;¨ú¥X·sªº¹Bºâ¤l°ïÅ|³»¤§¹Bºâ¤l
mov ch,isp[edx]
mov lpOpStack,esi
mov lpPostfix,edi
cmp dl,0ch
je check_buf ;Y¬Ûµ¥¡Aªí¥Ü¹Bºâ¤l°ïÅ|¤w¸gªÅ¤F
cmp cl,ch ;ÀˬdTOKEN¤§ICP¬O§_¤j©ó·s¹Bºâ¤l°ïÅ|³»¤§ISP
ja push_op_code ;Y¤j©ó¡A«h±NTOKEN±À¤J¹Bºâ¤l°ïÅ|
jmp pop_op_code ;Y¤p©óµ¥©ó¡A«h¼u¥X¹Bºâ¤l°ïÅ|³»¦Ü«á§Ç¦¡¦r¦ê
check_buf:
mov esi,ptCodeBuffer
cmp byte ptr [esi],0ffh
jnz push_op_code
postfix_ok:
mov al,current_code
mov edx,lpPostfix
mov [edx],al
inc lpPostfix
;¦Ü¦¹¤w±N¤¤§Ç¹Bºâ¦¡Âà´««á§Ç¹Bºâ¦¡¤w¸g³B²z§¹¦¨¤F
;¶}©lpºâ«á§Ç¹Bºâ¦¡¤§È
mov lpPostfix,offset stPostfix
mov lpNumStack,offset aryNumStack
mov lpNumTemp,offset aryNumTemp
mov esi,lpPostfix
mov edi,lpNumStack
nxt_tk: sub eax,eax
lodsb
mov edx,eax
shl edx,2
mov ecx,10
jmp action[edx]
number::mov edx,lpNumTemp ;¨ú±o¦baryNumTempªº¹Bºâ¤¸¡A¨CÓ¹Bºâ¤¸¥H¼È®É
@@: mov al,[edx] ;¹ê¼Æ«¬ºA¦s©ñ¡A²{¦bn§â¥¦²¾¨ìaryNumStackùØ
stosb
inc edx
loop @b
mov lpNumTemp,edx
mov lpNumStack,edi
jmp nxt_tk
plus:: sub edi,ecx ;EDI«ü¦VaryNumStackªº°ïÅ|³»
mov edx,edi ;EDX«ü¦VaryNumStackªº°ïÅ|³»ªº¤U¤@Ó
sub edx,ecx
fld tbyte ptr[edi]
fld tbyte ptr[edx]
fadd
return: fstp tbyte ptr[edx]
mov lpNumStack,edi
jmp nxt_tk
minus:: sub edi,ecx
mov edx,edi
sub edx,ecx
fld tbyte ptr[edx]
fld tbyte ptr[edi]
fsub
jmp return
multiple::
sub edi,ecx
mov edx,edi
sub edx,ecx
fld tbyte ptr[edi]
fld tbyte ptr[edx]
fmul
jmp return
divide::
sub edi,ecx
mov edx,edi
sub edx,ecx
fld tbyte ptr[edx] ; x ; ;
fld tbyte ptr[edi] ; y ; x ;
ftst
fstsw fpu_sw
fwait
mov ax,fpu_sw
sahf
jz equal_2_zero ;°£¥H¹s¬OµL·N¸qªº
fdiv ; x/y ; ;
jmp return
less_zero:
equal_2_zero:
fcompp
err_p: mov edx,offset szErrorMsg1
jmp error
negative::
mov edx,edi
sub edx,ecx
fld tbyte ptr[edx]
fchs
fstp tbyte ptr[edx]
jmp nxt_tk
exp10:: mov edx,edi
sub edx,ecx
fld tbyte ptr[edx]
fild dwTen
call x_p_y
jmp return
reciprocal::
mov edx,edi
sub edx,ecx ;--st0--;--st1--;
fld1 ; 1 ; ;
fld tbyte ptr[edx] ; x ; 1 ;
ftst ; x ; 1 ;¤ñ¸ûx¬O§_µ¥©ó¹s
fstsw fpu_sw
fwait
mov ax,fpu_sw
sahf
jz equal_2_zero ;Yxµ¥©ó¹s¡A¨ú¨ä˼ÆÈ¬OµL·N¸qªº
fdiv
fstp tbyte ptr[edx]
jmp nxt_tk
log:: mov edx,edi
sub edx,ecx ;--st0--;--st1--;
fld1 ; 1 ; ;
fld tbyte ptr[edx] ; x ; 1 ;
ftst ; x ; 1 ;¤ñ¸ûx¬O§_¤j©ó¹s
fstsw fpu_sw
fwait
mov ax,fpu_sw
sahf
jbe less_zero ;Yx¤p©ó©Îµ¥©ó¹s¡A«h¨ú¹ï¼ÆÈ¬OµL·N¸qªº
fyl2x ;1log2 x; ;
fldl2t ; log2 T; log2 x ;
fdiv
fstp tbyte ptr[edx]
jmp nxt_tk
exponent::
sub edi,ecx
mov edx,edi ;EDI=«ü¼Æ¦ì§}
sub edx,ecx ;EDX=©³¼Æ¦ì§}
fld tbyte ptr[edi]
fld tbyte ptr[edx]
call x_p_y ;¨DXªºY¦¸¤è(X=ST=©³¼Æ¡FY=ST(1)=«ü¼Æ)
jc err_p
jmp return
answer::sub edi,ecx
fld tbyte ptr[edi]
fstp qword ptr[edi]
invoke FloatToStr2,qword ptr [edi],offset szAnswer
mov edx,offset szAnswer
clc
complete: ret
Execute endp
;---------------------------------------------------------------------
DlgProc proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
.if uMsg==WM_COMMAND
mov eax,wParam
cmp lParam,0
jnz bt_ctrl
;¥H¤U¬O¨Ï¥ÎªÌÂI¿ï¿ï³æ
.if ax==IDM_EXIT
jmp exit
.elseif ax==IDM_CLEAR
invoke Initiation,hWnd
.elseif ax==IDM_PI
mov ecx,offset szPi
pi0: .if bIfExecute!=0
invoke Initiation,hWnd
.endif
mov edx,ptExpression
push edi
mov edi,ptCodeBuffer
pi1: mov al,[ecx]
inc ecx
or al,al
jz pi4
cmp al,'.'
jne pi2
mov [edx],al
mov al,0ah
jmp pi3
pi2: mov [edx],al
sub al,'0'
pi3: stosb
inc edx
jmp pi1
pi4: mov ptCodeBuffer,edi
mov ptExpression,edx
pop edi
jmp ctr4
.elseif ax==IDM_EULER
mov ecx,offset szEuler
jmp pi0
.endif
jmp not_deal
;¥H¤U¬O¨Ï¥ÎªÌ¿ï«ö«ö¶s
bt_ctrl:mov edx,eax
shr edx,16
cmp dx,BN_CLICKED
jne not_deal
cmp bIfExecute,0 ;Y¨Ï¥ÎªÌ¦b¤§«e¤w«ö¤U¡uEXE¡v«ö¶s¡A«hªí¥Ü¤w
jz ctr0 ;§¹¦¨pºâ¥ý«eªº¹Bºâ¦¡¡A¬G±o¥ýªì©l¤Æ¤@¨Ç¸ê®Æ
invoke Initiation,hWnd
ctr0: mov ecx,ptExpression ;Y¹Bºâ¦¡¤º¦r¤¸¶W¹L200«h¤£³B²z
sub ecx,offset szExpression
cmp cx,200
jae not_deal
.if ax>=3000
;Y¨Ï¥ÎªÌ¿é¤J¼Æ¦r©Î¤p¼ÆÂI¡A¨äÃѧO½X±q3000¨ì3010
sub ax,3000
mov ecx,ptCodeBuffer
mov [ecx],al
mov ecx,ptExpression
cmp al,10 ;Àˬd¬O§_¬°¤p¼ÆÂI¡A¤p¼ÆÂIªºÃѧO½X¬°3010
jne ctr1
sub al,0ch ;¬O¤p¼ÆÂI¡A«h¨ÏAL¦A¥[6¡A¤p¼ÆÂI¤º½X¬°0AH
ctr1: add al,'0'
mov [ecx],al
ctr2: inc ptExpression
ctr3: inc ptCodeBuffer
ctr4: invoke SetWindowText,hwndEdit,offset szExpression
;©³¤U¤T¦æ¬O¥Î¨Ó³]©w½s¿è®Ø¤º´å¼Ð(caret)¦ì¸m¦b³Ì«á¤@Ó¦r¤¸
mov ecx,ptExpression
sub ecx,offset szExpression
invoke SendMessage,hwndEdit,EM_SETSEL,ecx,ecx
invoke SetFocus,hwndEdit
.elseif ax==IDB_CLEAR ;¨Ï¥ÎªÌ«ö¤U¡uCLEAR¡v«ö¶s
invoke Initiation,hWnd
.elseif ax==IDB_EXECUTE ;¨Ï¥ÎªÌ«ö¤U¡uEXECUTE¡v«ö¶s
inc bIfExecute
mov ecx,ptCodeBuffer
mov byte ptr [ecx],1ch
invoke Execute
jc ctr5
mov edx,offset szAnswer
ctr5: invoke SetDlgItemText,hWnd,IDE_EXPRESSION,edx
.else ;¥H¤U¬O¨Ï¥ÎªÌ«ö¤U¹Bºâ¤l«ö¶s
sub ax,7c0h ;§â¹Bºâ¤lÂà´«¦¨¤º½X
mov ecx,ptCodeBuffer
mov [ecx],al
cmp al,19h ;Àˬd¬O§_«ö¤U˼ơB¹ï¼Æ¡B«ü¼Æ«ö¶s
jae ctr7
sub al,11h ;«ö¤U¥[´î¼°£¬A¸¹©Î10ªº¼¾«ö¶s
push ebx
mov ebx,offset display_table
xlat
pop ebx
ctr6: mov ecx,ptExpression
mov [ecx],al
jmp ctr2
ctr7: ;˼ơB¹ï¼Æ¡B«ü¼Æ«ö¶sªº¦r¤¸¤£¥u¤@Ó¡A¦bctr7:¨ìctr9:¤§¶¡ªºµ{¦¡¤ù¬q³B²z
.if al==19h
mov ecx,offset stReciprocal
jmp ctr8
.elseif al==1ah
mov ecx,offset stLOG
jmp ctr8
.elseif al==1bh
mov ecx,offset stExponent
jmp ctr8
.elseif al==1ch
mov al,'='
jmp ctr6
.endif
ctr8: mov edx,ptCodeBuffer
mov [edx],al
push edi ;¥H¤U11¦æ¬O¥Î¨Ó§âECX©Ò«ü¦r¦ê¡A¶ñ¤JptExpression¦ì§}¤¤
push esi
sub eax,eax
mov esi,ecx
lodsb
mov ecx,eax
mov edi,ptExpression
add ptExpression,ecx
rep movsb
pop esi
pop edi
ctr9: jmp ctr3
.endif
not_deal:
.elseif uMsg==WM_INITDIALOG
invoke GetDlgItem,hWnd,IDE_EXPRESSION
mov hwndEdit,eax
invoke Initiation,hWnd
invoke LoadIcon,hInstance,offset CalcIcon
invoke SendMessage,hWnd,WM_SETICON,ICON_SMALL,eax
.elseif uMsg==WM_CLOSE
exit: invoke EndDialog,hWnd,NULL
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
DlgProc endp
;---------------------------------------------------------------------
start: invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,offset DlgName,NULL,offset DlgProc,NULL
invoke ExitProcess,eax
;*********************************************************************
end start
©³¤U¬O¸ê·½´yzÀÉ¡ACALC.RC¡G
#include "c:\masm32\include\resource.h"
#define CalcMenu 1000
#define IDE_EXPRESSION 1000
#define IDB_CLEAR 1001
#define IDB_EXECUTE 1002
#define IDB_ADD 2001
#define IDB_SUB 2002
#define IDB_MUL 2003
#define IDB_DIV 2004
#define IDB_LPAREN 2005
#define IDB_RPAREN 2006
#define IDB_NEG 2007
#define IDB_EXP10 2008
#define IDB_RECIPROCAL 2009
#define IDB_LOG 2010
#define IDB_EXP 2011
#define IDB_N0 3000
#define IDB_N1 3001
#define IDB_N2 3002
#define IDB_N3 3003
#define IDB_N4 3004
#define IDB_N5 3005
#define IDB_N6 3006
#define IDB_N7 3007
#define IDB_N8 3008
#define IDB_N9 3009
#define IDB_DOT 3010
#define IDM_EXIT 3000
#define IDM_CLEAR 3001
#define IDM_PI 3002
#define IDM_EULER 3003
CalcIco ICON CALC2.ICO
CalcMenu MENU
BEGIN
MENUITEM "Â÷¶}",IDM_EXIT
MENUITEM "²M°£",IDM_CLEAR
POPUP "±`¼Æ"
BEGIN
MENUITEM "¶ê©P²v",IDM_PI
MENUITEM "¤×©Ô¼Æ",IDM_EULER
END
END
CalcDlg DIALOG 0,0,111,108
STYLE DS_SETFONT |WS_POPUP |WS_CAPTION |WS_VISIBLE |WS_SYSMENU
FONT 9,"Cambria"
MENU CalcMenu
CAPTION "WANKER'S pºâ¾÷"
BEGIN
CONTROL "" ,IDE_EXPRESSION,"EDIT" ,ES_LEFT|WS_BORDER|ES_AUTOHSCROLL|ES_READONLY,3,3,105,12
PUSHBUTTON "10^x" ,IDB_EXP10 , 3, 18, 24, 12
PUSHBUTTON "^(-1)",IDB_RECIPROCAL, 30, 18, 24, 12
PUSHBUTTON "LOG" ,IDB_LOG , 57, 18, 24, 12
PUSHBUTTON "x^y" ,IDB_EXP , 84, 18, 24, 12
PUSHBUTTON "+/-" ,IDB_NEG , 3, 33, 24, 12
PUSHBUTTON "(" ,IDB_LPAREN , 30, 33, 24, 12
PUSHBUTTON ")" ,IDB_RPAREN , 57, 33, 24, 12
PUSHBUTTON "¡Ò" ,IDB_DIV , 84, 33, 24, 12
PUSHBUTTON "7" ,IDB_N7 , 3, 48, 24, 12
PUSHBUTTON "8" ,IDB_N8 , 30, 48, 24, 12
PUSHBUTTON "9" ,IDB_N9 , 57, 48, 24, 12
PUSHBUTTON "¡Ñ" ,IDB_MUL , 84, 48, 24, 12
PUSHBUTTON "4" ,IDB_N4 , 3, 63, 24, 12
PUSHBUTTON "5" ,IDB_N5 , 30, 63, 24, 12
PUSHBUTTON "6" ,IDB_N6 , 57, 63, 24, 12
PUSHBUTTON "-" ,IDB_SUB , 84, 63, 24, 12
PUSHBUTTON "1" ,IDB_N1 , 3, 78, 24, 12
PUSHBUTTON "2" ,IDB_N2 , 30, 78, 24, 12
PUSHBUTTON "3" ,IDB_N3 , 57, 78, 24, 12
PUSHBUTTON "+" ,IDB_ADD , 84, 78, 24, 12
PUSHBUTTON "0" ,IDB_N0 , 3, 93, 24, 12
PUSHBUTTON "." ,IDB_DOT , 30, 93, 24, 12
PUSHBUTTON "CLEAR",IDB_CLEAR , 57, 93, 24, 12
PUSHBUTTON "EXE" ,IDB_EXECUTE , 84, 93, 24, 12
END
©³¤U¬O»s§@ÀÉ¡ACALC.MAK¡G
NAME=CALC
ALL:$(NAME).exe
$(NAME).exe: $(NAME).asm $(NAME).res
ml $(NAME).asm /link $(NAME).res
$(NAME).res: $(NAME).rc CALC2.ICO
rc $(NAME).rc
n»s§@¥i°õ¦æÀɮɡA»Ýn§â CALC.ASM¡BCALC.MAK¡BCALC.RC¡BCALC2.ICO ¥|ÓÀɮשñ¦b¦P¤@¤l¥Ø¿ý¡A¶}±Ò¡u©R¥O´£¥Ü¦r¤¸¡v¡A§Q¥Î¡ucd¡v«ü¥O¤Á´«¨ì§t¦³©Ò¦bªº¤l¥Ø¿ýùØ¡A¦A¿é¤J¡unmake -f calc.mak¡v§Y¥i±o CALC.EXE ¥i°õ¦æÀÉ¡A¹Lµ{¦p¤U¡G
E:\HomePage\SOURCE\CALC>nmake -f calc.mak [Enter]
Microsoft (R) Program Maintenance Utility Version 1.50
Copyright (c) Microsoft Corp 1988-94. All rights reserved.
rc CALC.rc
ml CALC.asm /link CALC.res
Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997. All rights reserved.
Assembling: CALC.asm
Microsoft (R) Incremental Linker Version 5.12.8078
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
/SUBSYSTEM:WINDOWS
"CALC.obj"
"/OUT:CALC.exe"
"CALC.res"
E:\HomePage\SOURCE\CALC>
CALC ªºpºâ¬yµ{¤jP¤À¬°¨â¶¥¬q¡G³B²z¨Ï¥ÎªÌ¿é¤Jªº¸ê®Æ©Mpºâµ²ªG¡C²Ä¤@¶¥¬q¬O³B²z¨Ï¥ÎªÌ¿é¤Jªº¸ê®Æ¡A¦b³o¶¥¬q¤¤¡A³Ì¥Dnªº¤u§@¬O§â¨Ï¥ÎªÌ©Ò¿é¤Jªº«ö¶s¡AÂàÅܦ¨¤@ÓÓªº¡u¤º½X¡v¦s©ó stCodeBuffer ùØ¡C¨Ò¦p¨Ï¥ÎªÌ¨Ì§Ç«ö¤U¡u7¡v¡u+¡v¡uLOG¡v¡u2¡v¡u0¡v¡uEXE¡v¤»Ó«ö¶s¡AstCodeBuffer ·|¦s¤J 7¡B11H¡B1AH¡B2¡B0¡B1CH ³o¨Ç¤º½X¡C¤p¤ì°¸§â¼ÆÈªº¤º½X³W¹º¦¨ 0¡ã0AH ( 0¡ã9 ªí¥Ü¼ÆÈ¡A0AH ªí¥Ü¤p¼ÆÂI )¡A¦Ó¡u¡Ï¡v¡u¡Ð¡v¡u¡Ñ¡v¡u¡Ò¡v¡u(¡v¡u)¡vµ¥¹Bºâ¤lªº¤º½X±q 11H¡B12H¡K¡K¶}©l¡C( 0BH¡ã10H ¨S¦³¥Î¨ì )
°£¦¹¤§¥~¡ACALC ÁÙ·|§â¨Ï¥ÎªÌ©Ò¤Uªº¨C¤@Ó«ö¶s°O¿ý¡A¥H¦r¤¸ªº¤è¦¡°O¿ý¦b szExpression ¦r¦êùØ¡C¥H¤W±¬°¨Ò¡A·í¨Ï¥ÎªÌ¨Ì§Ç«ö¤U¡u7¡v¡u+¡v¡uLOG¡v¡u2¡v¡u0¡v¡uEXE¡v¤»Ó«ö¶s«á¡AszExpression ·|¦s¤J¡u7+LOG20=¡v³oÓ¦r¦ê¡C·íµM¡AszExpression ¦r¦ê»P stCodeBuffer ¬O¦P¨Bªº¡C³o¬qµ{¦¡¦b¼Ð°O bt_ctrl: ¨ì not_deal: ¤§¶¡¡C
¦b²Ä¤@¶¥¬q¤¤¡A¦³´XÓ¦a¤èȱo¤@´£¡C²Ä¤@Ó¬O·í¨Ï¥ÎªÌ¿é¤Jªº¸ê®Æ«Ü¦h¦Ó¶W¹L½s¿è®Ø©Ò¯àÅã¥Üªº½d³ò®É¡AÀ³¸Ón§â³Ì«á¤@Ó¦r¤¸Åã¥Ü¦b½s¿è®Ø¥kÃä¡C¤p¤ì°¸§ä¤F³\¦h¸ê®Æ¡A¦ü¥GµL¥Î¡A³Ì«á¥u±o¥Î¤@ÓÅܳqªº¤èªk¡A¨º´N¬O§Q¥Î¦b½s¿è®Ø¤¤¿ï©w¤@¬q¤å¦r¡A³o¼Ë¥i¥H¢¨Ï½s¿è®Øªº´å¼Ð ( caret ) ²¾¦Ü¿ï©wªº¤å¦r¡C§ÚÌ¥i¥H¹ï½s¿è®Øµo¥X EM_SETSEL °T®§¨Ó¿ï©w¤å¦r¡C
CALC ªº²Ä¤G¶¥¬q¬Opºâ¡A¥ç§Y¨Ï¥ÎªÌ«ö¤U¡uEXE¡v¤§«áªº¹Lµ{¡C¦¹¹Lµ{ªº²Ä¤@¨B¬O§â bIfExecute ÅܼƳ]¬°¤@¡Aªí¥Ü¤w«ö¤U¡uEXE¡v«ö¶s¡C·Q·Q§Ṳ́@¯ë¨Ï¥Îpºâ¾÷®É¡A«ö¤U¡u¡×¡v«á·|¦b²G´¹¿Ã¹õÅã¥Üpºâµ²ªG¡A¦pªGÁÙn¦AÄ~Äòpºâ¤U¤@Ӻ⦡¡A¤£¶·«ö¡uC¡v¡A¥iª½±µ«ö¥ô¦ó¤@«ö¶s´N·|²M°£©Ò¦³°O¿ý¡CbIfExecute ªº³]©w´N¬O¬°¤F¦¹¤@¥Øªº¡A·í¨Ï¥ÎªÌ«ö¤U¥ô¤@«ö¶s¡A·|¥ýÀˬd bIfExecute ¬O§_¬°¤@¡A¦pªG¬Oªº¸Üªí¥Ü«e¤@¦¸«ö¤Uªº«ö¶s¬O¡uEXE¡v¡AÀ³¥ý°õ¦æ Initiation °Æµ{¦¡¡A²M°£ szExpression¡BstCodeBuffer ¤§«á¡A¦A³B²z¨ä¥L¨Æ±¡¡C
±µµÛ CALC ¶}©lpºâ¨Ï¥ÎªÌ©Ò¿é¤J¹Bºâ¦¡¤F¡C©Ò¦³pºâªº¹Lµ{³£¦b Execute °Æµ{¦¡¤¤°õ¦æ¡AExecute °Æµ{¦¡·|¥ý¦b stCodeBuffer ¦r¦êùجD¿ï¥X¨C¤@Ó TOKEN¡C©Ò¿× TOKEN ¬O«ü¨CӺ⦡¤¤ªº¹Bºâ¤l©Î¹Bºâ¤¸ ( ¤p¤ì°¸¤£ª¾¦p¦ó½Ķ³oÓ¦r¡A¬Gª½±µ¥Hì¤åªí¥Ü )¡A¨Ò¦p¤W±©Ò¿é¤Jªº¹Bºâ¦¡¬O¡u7+LOG20=¡v¡A²Ä¤@Ó TOKEN ¬O 7¡A²Ä¤GÓ TOKEN ¬O +¡A²Ä¤TÓ¬O LOG¡A²Ä¥|Ó¬O 20¡A³Ì¥½¤@Ó¬O =¡A¬D¥X¤@ÓÓ TOKEN ªº¤u§@¥Ñ GetToken °Æµ{¦¡t³d¡C
GetToken Àˬd¤º½X¬O§_¶W¹L 0BH ¨Ó§PÂ_©Ò¨ú±oªº¬O¹Bºâ¤lÁÙ¬O¹Bºâ¤¸¡A¦p«e±©Ò»¡¡A¤p¤ì°¸¥H 0¡ã0AH ªí¥Ü¼ÆÈ¡A¶W¹L³o½d³ò§Y¬°¹Bºâ¤l¡CY¬°¼ÆÈ¡A«h°õ¦æ¼Ð°O gt1: ¨ì gt7: ¤§¶¡ªºµ{¦¡¡A³o¬qµ{¦¡·|¤£Â_ªº±q stCodeBuffer ¤¤Åª¨ú¤@ÓÓªº¼ÆÈ¤º½X¡Aª½¨ì¤£¬O¼ÆÈ¬°¤î¡C¥¦·|§â©Ò±oªº¼ÆÈ¦s¦b ST(0) ùØ¡A¨Ã¥B§â current_code ³]¬°¹s¡C¦pªG¬O¹Bºâ¤lªº¸Ü¡A«h§â¤º½X´î¥h 10H ·í¦¨ current_code¡C
¨C¦¸¨ú±o¤@Ó TOKEN «á¡A±µµÛn°µªº¨Æ¬OÀˬd¨Ï¥ÎªÌ©Ò¿é¤Jªº»yªk¬O§_¥¿½T¡A¨Ò¦p¨Ï¥ÎªÌ¤£¯à¿é¤JÃþ¦ü¡u7+*LOG20¡v³oºØ¹Bºâ¦¡¡C³o¬qÀˬd»yªk¥¿½T»P§_ªºµ{¬O¦b check: ¼Ð°O»P syntax_error: ¼Ð°O¤§¶¡¡CÀˬdªº¤èªk¬O§Q¥Î¤@±i¥s°µ¡uparse table¡vªí®æÀˬd¡Aparse table ªºÁa®y¼Ð»P¾î®y¼Ð¤À§O¬O¦UºØ¤£¦Pªº TOKEN ( ¹Bºâ¤l©Î¹Bºâ¤¸ )¡A¦p¤Uªí¡C¦b³oªí®æùØ¡A¹Bºâ¤¸¥Î 0 ªí¥Ü¡A¥[¡B´î¡B¼¡B°£¡B¥ª¬A¸¹¡B¥k¬A¸¹¡Bt¸¹¡B10x¡Bx¡Ð1¡BLOG¡Bxy¡Bµ¥©ó¤À§O¥Î 1¡B2¡B3¡B4¡B5¡B6¡B7¡B8¡B9¡B0AH¡B0BH¡B0CH ªí¥Ü¡C¥i¥H¬Ý¥X¨Ó¡A¹Bºâ¤l¦b parse table ¤¤ªº¥N½X»P¤º½X¬Û®t 10H¡C
;parse table (x,y)=(²{¦bªº,«e¤@Óªº)
; 10 L
; ¾ËO «ü
; N + - * / ( ) - ¤è¼ÆG ¼Æ=
; 0 1 2 3 4 5 6 7 8 9 A B C
parse_table BYTE 0,1,1,1,1,0,1,0,1,1,0,1,1 ;0 N
BYTE 1,0,0,0,0,1,0,1,1,0,1,0,0 ;1 +
BYTE 1,0,0,0,0,1,0,1,1,0,1,0,0 ;2 -
BYTE 1,0,0,0,0,1,0,1,1,0,1,0,0 ;3 *
BYTE 1,0,0,0,0,1,0,1,1,0,1,0,0 ;4 /
BYTE 1,0,0,0,0,1,0,1,1,0,1,0,0 ;5 (
BYTE 0,1,1,1,1,0,0,0,0,1,0,1,1 ;6 )
BYTE 1,1,1,1,1,1,0,2,1,0,1,0,0 ;7 -(t¸¹)
BYTE 1,0,0,0,0,1,0,1,0,0,1,0,0 ;8 10¾¤è
BYTE 0,1,1,1,1,0,1,0,0,1,0,0,1 ;9 x¡Ð1˼Æ(R)
BYTE 1,0,0,0,0,1,0,1,1,0,1,0,0 ;A LOG
BYTE 1,0,0,0,0,1,0,1,1,0,1,0,0 ;B xy«ü¼Æ
BYTE 1,0,0,0,0,1,0,1,1,0,1,0,1 ;C =
©³¤U¡A¤p¤ì°¸µy·L¸ÑÄÀÀˬd»yªk¹Lµ{¡C¹Bºâ¦¡»yªkªº¥¿½T»P§_¡A¬O¨Ì¾Ú¤W¤U¤å¨Ó¨M©w¡A¦pªG¨Ï¥ÎªÌ¿é¤J¡u7+*LOG20¡v³oºØ¹Bºâ¦¡¡A7 »P + ³s¦b¤@°_¬O¦X²zªº¡A¦ý¬O + »P * ³s¦b¤@°_´N¬O¿ù»~ªº¡C¥H¤W±¬°¨Ò¤l¡G·í²Ä¤@Ó TOKEN¡A7 ³Q¨ú¥X«á¡A¦¹¬°¹Bºâ¤¸¡A¬G current_code ¬° 0¡A»P«e¤@Ó TOKEN ¤ñ¸û ( «e¤@Ó TOKEN ¬°¡u=¡v¡Aprevious_code ¬° 0CH¡A¦b¤@¶}©l´N¥ý°²³]²Ä¹sÓ TOKEN ¬O¡u=¡v )¡A¦b parse_table ¬d¥X¬°¤@ ( ¤WªíÂŦâ¦r )¡A¬G»yªk¥¿½T¡C±µµÛ¨ú¥Xªº TOKEN ¬O¡u+¡v¡A»P«e¤@ TOKEN¡A¹Bºâ¤¸¡A¤ñ¸û¡B¬dªí¡A±o¨ì¤@ ( ¤Wªí¥Õ¦â¦r )¡C±µµÛ¨ú¥Xªº TOKEN ¬O¡u*¡v¡A»P«e¤@ TOKEN¡A¡u+¡v¡A¤ñ¸û¡B¬dªí±o¹s ( ¤Wªí¬õ¦r )¡Aµo¥Í»yªk¿ù»~¡C©Ò¥H parse table ªº¥Îªk¬O¥ý®Ú¾Ú«e¤@Óªº TOKEN ¬d¥XÁa®y¼Ð¡A¦A¥Ñ·í«e TOKEN ¬d¾î®y¼Ð¡A§Y¥i±o¤W¤U¤å¬O§_¥¿½T¡C
Y»yªk¥¿½T¡A±µ¤U¨Óªº¨BÆJ´N¬O§â¤¤§Ç¹Bºâ¦¡Åܦ¨«á§Ç¹Bºâ¦¡¡A¨ä¤èªk¤w¦b«e±±Ôz¹L¤F¡A´N¤£¦A¦h»¡¡C¦¹³Bȱo¤@´£ªº¬O¡Aµ¥¨ì¦b stCodeBuffer ùةҦ³¤º½X³£³B²z§¹²¦«á¡A«á§Ç¹Bºâ¦¡·|¦s¦b stPostfix ¦r¦êùØ¡A¨Ò¦p¨Ï¥ÎªÌ¿é¤J¡u7+LOG20=¡vªº«á§Ç¹Bºâ¦¡¬°¡u7 20 LOG +¡v¡C¦ý¬O¦b stPostfix ¦r¦êùØ¥H¤@Ӧ줸²Õªí¥Ü¤@Ó TOKEN¡A¹Bºâ¤lªø¶È¤@Ӧ줸²Õ¨S¦³°ÝÃD¡A¦Ó¹Bºâ¤¸µLªk¥H¤@Ӧ줸²Õªí¥Ü¡C¤p¤ì°¸¥H¹sªí¥Ü¦¹ TOKEN ¬°¹Bºâ¤¸¨Ó¸Ñ¨M³oÓ°ÝÃD¡A¦Ó¯u¥¿ªº¹Bºâ¤¸«h¦s©ó aryNumTemp °}¦CùØ¡A¦¹°}¦C¥i¦s©ñ 50 Ó¹Bºâ¤¸¡A¨CÓ¹Bºâ¤¸¬O 10 ¦ì¤¸²Õªøªº¼È®É¹ê¼Æªº®æ¦¡¦s©ñ¡A¥H²Å¦X 80x87 ªº¹Bºâ¡C©Ò¥H³Ì«á©Ò±oªº stPostfix ¬O¡u0 0 0AH 1 0CH¡v¡A¦Ó aryNumTemp °}¦C«h¦s¤J 7¡B20 ªº¼È®É¹ê¼Æ®æ¦¡¡C
ºò±µµÛªº¨BÆJ¬Opºâ«á§Ç¹Bºâ¦¡¡A¨ä¤èªk¤]¦b«e±´£¹L¤F¡A¦¹³B¤]¤£¦h»¡¡C¦ý¦bµ{¦¡ªº¼g§@¤W±¡A¤p¤ì°¸¥Î¤F¨âÓ§Þ¥©¡C¤@¬O stPostfix ¬°«á§Ç¹Bºâ¦¡¡Aùر¦s¦³¨Ï¥ÎªÌ¿é¤Jªº¹Bºâ¤¸»P¹Bºâ¤l¡A¹Bºâ¤¸¥H 0 ªí¥Ü¡A¦Ó¯u¥¿ªº¹Bºâ¤¸«h¦s©ó aryNumTemp ùØ¡A»P stPostfix ¬Û¹ïÀ³¡CaryNumStack «h¬O¹Bºâ¤¸°ïÅ|¡A¬O¥Î¨ÓÀx¦s¹Bºâ¤¸ªº¡A«e±´£¹L¡A«á§Ç¹Bºâ¦¡pºâµ²ªG®É¡A¹J¹Bºâ¤¸«h§â¹Bºâ¤¸¦s©ó¹Bºâ¤¸°ïÅ|¤¤¡A¹J¹Bºâ¤l®É«h¦r¹Bºâ¤¸°ïÅ|¨ú¥X¹Bºâ¤¸pºâ¡C¤G¬Opºâ®É¶·¨Ì¾Ú¦U¹Bºâ¤l¸õ¨ì¤£¦Pªºµ{¦¡³B°õ¦æ¡A¦¹³B¤p¤ì°¸¤£¥H .if/.elseif/.endif ªº¤èªkÀˬd¡A¦Ó¥Î©³¤Uªº¤èªk¡G
action DWORD number,plus,minus,multiple,divide,0,0,negative
DWORD exp10,reciprocal,log,exponent,answer
¡K¡K¡K¡K¡K¡K¡K¡K
jmp action[edx]
number:: ;³B²z¹Bºâ¤¸¡A¥ç§Y±À¤J aryNumStack
¡K¡K¡K¡K¡K¡K¡K¡K
plus:: ;¥[ªk
¡K¡K¡K¡K¡K¡K¡K¡K
minus:: ;´îªk
¡K¡K¡K¡K¡K¡K¡K¡K
multiple:: ;¼ªk
¡K¡K¡K¡K¡K¡K¡K¡K
³oºØ¤è¦¡¬O§â¦UӼаO ( number::¡Bplus::¡Bminus::¡K¡K) ªº¦ì§}¡A³£¦¬¶°°_¨Ó¶°¦X¦¨ action °}¦C¡AµM«á¥H EDX ¬°¯Á¤Þ°õ¦æ¸õÅD«ü¥O¡C¤]´N¬O»¡¡Aaction °}¦C¨ä¹ê¬O number::¡Bplus::¡Bminus::¡K¡Kµ¥¼Ð°O¦ì§}©Ò²Õ¦¨ªº°}¦C¡A¨C¤@¼Ð°O©Ò³Bªº¦ì§}¦û¦³¥|Ӧ줸²Õ¡A©Ò¥H¥un§â¹Bºâ¤lªº TOKEN ȼ¥H¥|¡A´N¥i±o¥H action ¬°°ò·Çªº°¾²¾¦ì§}¡AµM«á¥H JMP «ü¥O¸õÅD¦Ü¦¹¦ì§}°õ¦æ©Ò¹ïÀ³ªº¹Bºâ¡C¥t¦³¤@¥ó¨ÆÈ±oª`·N¡A¤@¯ë©w¸q¼Ð°O¬O¥Î¡G
²Å¸¹¦W:
¦Ó¦¹³B«h¬O¥Î
²Å¸¹¦W::
«áªÌ¦h¤F¤@Ó«_¸¹¡A¤£¦P¤§³B¦b©ó«eªÌ©Ò¯à§@¥Îªº½d³ò¬O©Ò©w¸qªº°Æµ{¦¡¡AÄݩ󧽳¡ªº¡F¦Ó«áªÌ©Ò¯à§@¥Îªº½d³ò¬O¤½¥Îªº¡AÄÝ©ó¥þ°ìªº¡C¦pªG±z§â¡unumber::¡v¼g¦¨¡unumber:¡v¡A¨º»ò¦b²ÕͮɡAMASM ·|§i¶D±z¡uerror A2006: undefined symbol : plus¡v¡C
FloatToStr/2 ¬O MASM32 Ver. 7 ©Ò´£¨Ñªº¤@ӰƵ{¦¡¡AÅU¦W«ä¸q¡A¥¦ªº¥Øªº¬O§â¤@Ó¥|¦r²Õ ( QWORD ) ªº¯BÂI¼ÆÂàÅܦ¨¤@Ó ASCII ¦r¦ê¡A¨ä쫬¬°¡G
FloatToStr2 proto stdcall fpin:QWORD, szDbl:PTR CHAR
¦b¡uX:\masm32\masm32.inc¡vÀÉ®×ùØ¡A¥]§t¤F FloatToStr2 ªºì«¬¡A¦]¦¹§ó²³æªº¤èªk¬Oª½±µ¥]§t mams32.inc ¥H¤Î¨äµ{¦¡®w¡C( ¦b X:\masm32\masm32.hlp ¦³ FloatToStr2 ¤Î¨ä¥L°Æµ{¦¡¨Ï¥Î¤èªkªº»¡©ú¡A³o¨ÇÀ³¸Ó³£¬O¼¶¼g Win32 ²Õ¦X»y¨¥ªº«e½ú¤ß¦åµ²´¹¡A¦Ó³Q MASM32 ¦¬¿ý¡C)