ªþ¿ý¤G¡@°ïÅ|ªºÀ³¥Î¡Ð¡Ð¼Æ¾Ç¹Bºâ¦¡

³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ºâ¦¡ ( infix notation ) »P«á§Ç¹Bºâ¦¡ ( postfix notation )

²¤¶

¤@¯ë¦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ºâ¦¡

«á§Ç¹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

  1. ¥ý§â¹Bºâ¤l»P¨ä¨â®Çªº¹Bºâ¤¸¥H¤@¹ï¤p¬A¸¹¬A°_¨Ó¡A§Y¨Ï¬O­¼¸¹»P°£¸¹¤]¤@¼Ë¡C
  2. ¤ÏÂÐÀˬd¨C­Ó¹Bºâ¤l³£¥²¶·¥[¤W¬A¸¹¡A¦]¦¹¥i¯à·|¦³¦n´X¼h¬A¸¹¡C
  3. ¥Ñ³Ì¤º¼h¶}©l¡A§â¨C­Ó¹Bºâ¤¸¤§¶¡ªº¹Bºâ¤l²¾¨ì¨C¤@¹ï¬A¸¹ªº¥k¬A¸¹¤W¡A¦A§â¬A¸¹°£¥h¡C

¨Ò¦p­n§â 2+5*6-4*8 Åܦ¨«á§Ç¦¡¡A¨Ì¾Ú¤W­±ªº­ì«h¡A¦Ó¦³©³¤U¨BÆJ¡G

  1. ¥ý§â¨C­Ó¹Bºâ¤l»P¨âÃ䪺¹Bºâ¤¸¥[¤W¬A¸¹¡A©ó¬OÅܦ¨ 2+(5*6)-(4*8)¡C
  2. ¦ý¬O¶È³o¼Ë¬O¤£°÷ªº¡A¦]¬°¥[»P´î©|¥¼¥[¬A¸¹¡A©Ò¥H­ì¦¡¦A«×Åܦ¨¡a [ 2 + ( 5*6 ) ] - ( 4*8 ) ¡b¡A¬°¤Fªí¥Ü 2 ¥[ (5*6) ¤§µ²ªG¡A©Ò¥H¥[¤W¤@¹ï¤¤¬A¸¹¡A[ ]¡F¤S¬°¤F¬Û´î¡A¦A¥[¤W¤@¹ï¤j¬A¸¹¡A¡a¡b¡C
  3. µM«á¥Ñ¤º¦Ó¥~¡A¥Î¬A¸¹ùتº¹Bºâ¤l¨ú¥N¡u ) ¡v¡A¦A®ø¥h¡u ( ¡v¡A©Ò¥HÅܦ¨¡a[ 2 + 5 6 * ] - 4 8 *¡b¡C
  4. ±µµÛ¦A²¾¤¤¬A¸¹ùتº¹Bºâ¤l¨ì¡u ] ¡v¦ì¸m¡A¥h±¼¡u [ ¡v¡A©ó¬OÅܦ¨¡a2 5 6 * + - 4 8 *¡b¡C­nª`·Nªº¬O¥Õ¦â»P¬õ¦âªº¨â³¡¥÷³£¤w³B²z¹L¤F¡A¥u³Ñ¤U´î¸¹¥¼³B²z¡C
  5. ¥Î´î¸¹¨ú¥N¡u¡b¡v¦ì¸m¡A¦A®ø¥h¡u¡a¡v¡A©Ò¥H³Ì«áµ²ªGÅܦ¨ 2 5 6 * + 4 8 * -¡A³o­Ó´N¬O 2+5*6-4*8 ªº«á§Ç¦¡¡C

ÁöµM±`¥Îªº¹Bºâ¤l¡A¦p¡G¥[¡B´î¡B­¼¡B°£»Ý­n¦³¨â­Ó¹Bºâ¤¸¤~¥i¹Bºâ¡F¦ý¬O¤]¦³¤@¨Ç¹Bºâ¤l¥u»Ý¤@­Ó¹Bºâ¤¸´N¥i¹Bºâ¤F¡A¨Ò¦p­t¸¹¡B¹ï¼Æ ( log )¡B¤T¨¤¨ç¼Æµ¥¡C¦pªG¹Bºâ¦¡¤¤¦³³o¨Ç¹Bºâ¤l¡A·Q­n§â¥¦Åܦ¨«á§Ç¹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

  1. ¥ý¥[¤W¬A¸¹¡AÅܦ¨¡a2 + [ 5 * ( LOG 3 ) ]¡b¡C
  2. ¥h±¼³Ì¤º¼h¤p¬A¸¹¡A¦P®É¥Î LOG ¨ú¥N¡u ) ¡v¡AÅܦ¨ ¡a2 + [ 5 * 3 LOG ]¡b¡C
  3. ¥Î­¼¸¹¨ú¥N¡u ] ¡v¡A¨Ã®ø¥h¡u [ ¡v¡A©ó¬OÅܦ¨ ¡a 2 + 5 3 LOG * ¡b¡C
  4. ³Ì«áÅܦ¨ 2 5 3 LOG * +¡A´N¬O«á§Ç¹Bºâ¦¡¡C

¤W­±¬O¤HÃþ¥H¤j¸£§â¤¤§Ç¦¡§ï¦¨«á§Ç¦¡ªº¹Lµ{¡A¦b²Õ¦X»y¨¥¹Bºâ¤¤¡A­n§â¤¤§Ç¦¡§ï¦¨«á§Ç¦¡¡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µ{¦¡¤¤§â¤¤§Ç¹Bºâ¦¡Âà´«¦¨«á§Ç¹Bºâ¦¡

¦b¹ê§@¤W¡A­n§â¤¤§Ç¹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

  1. ¨C¦¸¨ú¥X¤@­Ó¹Bºâ¤¸©Î¹Bºâ¤l¡C
  2. ­Y¬°¹Bºâ¤¸¡A«hª½±µ§â³o¹Bºâ¤¸¿é¥X¨ìÀx¦s«á§Ç¹Bºâ¦¡ªº¦r¦ê¤¤¡C
  3. ­Y¬°¹Bºâ¤l¡A¥i¥H¤À¬°¤U­±´XºØ±¡§Î¡G
    1. ­Y¬°¡u(¡v¡A«hª½±µ±À¤J¹Bºâ¤l°ïÅ|¤¤¡C
    2. ­Y¬°¡u)¡v¡A«h§â°ïÅ|¹Bºâ¤l¤¤ªº¹Bºâ¤l¨Ì§Ç¨ú¥X¡A¨Ã¿é¥X¨ì«á§Ç¦¡¦r¦êùØ¡Aª½¨ì¬Û¹ïÀ³ªº¡u(¡v¬°¤î¡C¦Ó·í«eªº¹Bºâ¤l¡A¡u)¡v¡A«h®ø¥¢¤£±À¤J¹Bºâ¤l°ïÅ|¡C
    3. ­Y¬°¨ä¥L¹Bºâ¤¸¡A«h¤ñ¸û¹Bºâ¤l¤§Àu¥ý¦¸§Ç¡C¦pªG·í«e¹Bºâ¤l¤§Àu¥ý¦¸§Ç ( ICP¡Ain-coming priority ) ¤j©ó°ïÅ|³»¹Bºâ¤l¤§Àu¥ý¦¸§Ç ( ISP¡Ain-stack priority )¡A«h§â·í«e¹Bºâ¤l±À¤J¹Bºâ¤l°ïÅ|¡F§_«h¦Û¹Bºâ¤l°ïÅ|³»ºÝ¨ú¥X¹Bºâ¤¸¿é¥X¦Ü«á§Ç¦¡¦r¦ê¡Aª½¨ì·í«e¹Bºâ¤l¤§ ICP ¤p©ó¹Bºâ¤l°ïÅ|³»¤§¹Bºâ¤lªº ISP ¬°¤î¡A¦A§â·í«e¹Bºâ¤l±À¤J°ïÅ|¡C
  4. ­«½Æ¨BÆJ 1¡ã3¡Aª½¨ì©Ò¦³ªº¹Bºâ¤¸©Î¹Bºâ¤l³£¤w¸g³B²z§¹²¦®É¡A¨Ì¦¸§â¹Bºâ¤l°ïÅ|¤¤ªº¹Bºâ¤l¨ú¥X¡A±À¤J«á§Ç¦¡¦r¦êùØ¡C

«á§Ç¦¡¹Bºâ¦¡­pºâµ²ªG

ÁöµM«á§Ç¹Bºâ¦¡¤£©ö²z¸Ñ¡A¦ý¬O¥¦¦³¨â­Ó¦n³B¡C¤@¬O¨S¦³¬A¸¹¡A¤G¬O²Å¦X­pºâ¾÷¹B§@¤è¦¡¡C³o¨â¥y¸Üªº·N«ä¬O¨Ï¥Î«á§Ç¹Bºâ¦¡®É¡A¤£»Ý­n¦Ò¼{¹Bºâ¤lªºÀu¥ý§Ç¡C°²¦p§Ú­Ì¤w¸g¨Ì·Ó¤W­z¤èªk§â¤¤§Ç¹Bºâ¦¡Âà´«¦¨«á§Ç¹Bºâ¦¡¥H«á¡A­n­pºâµ²ªG¡A´N«Ü²³æ¤F¡C³o®É¥u»Ý­n·Ç³Æ¤@­Ó°ïÅ|¡A³o­Ó°ïÅ|¥Î¨Ó¦s©ñ¹Bºâ¤¸¡AºÙ¬°¹Bºâ¤¸°ïÅ|¡C­pºâ®É¡A§â«á§Ç¹Bºâ¦¡°²·Q¦¨¤@­Ó¦r¦ê¡A¥Ñ¦¹¦r¦êªº¥ªÃä¦V¥k¶}©l­pºâ¡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ºâ¤l­pºâ¡AµM«á¦A§âµ²ªG±À¤J¹Bºâ¤¸°ïÅ|¡C¦p¦¹¤@ª½­«½Æ³o­Ó¨BÆJ¡Aª½¨ì«á§Ç¦¡¦r¦ê¤w¸gªÅ¤F¡A³o®É¦b¹Bºâ¤¸°ïÅ|ªº¼Æ­È´N¬O³Ì«áªºµ²ªG¡C


CALC ­ì©l½X

©³¤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²ÕÅܦ¨¦V­tµ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   ;       ;¦V­tµ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¡G­Y¿ù»~(¹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§_¬°¼Æ­È¡A­Y¬°¼Æ­È¡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¬O­t¸¹©ÎªÌ´î¸¹¡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¡A­Y´¿
        jne     gt4             ;¸g«h¸õ¦Ügt4¡F­Y§_«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¡A­YCYªí¥Ü¿é¤J¦³°ÝÃD¡C­YNCªí¥Ü¨S°ÝÃD¡A­Y¦¹TOKEN¬°¼Æ­È¡A«h¸Ó¼Æ­È
;¦s©óST(0)¡Acurrent_code¬°0¡F­Y¦¹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¡F­Y¬°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

;¶}©l­pºâ«á§Ç¹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²{¦b­n§â¥¦²¾¨ì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¸ê·½´y­zÀÉ¡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>

¸Ñ»¡

³B²z¨Ï¥ÎªÌ¿é¤Jªº¸ê®Æ

CALC ªº­pºâ¬yµ{¤j­P¤À¬°¨â¶¥¬q¡G³B²z¨Ï¥ÎªÌ¿é¤Jªº¸ê®Æ©M­pºâµ²ªG¡C²Ä¤@¶¥¬q¬O³B²z¨Ï¥ÎªÌ¿é¤Jªº¸ê®Æ¡A¦b³o¶¥¬q¤¤¡A³Ì¥D­nªº¤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

­pºâµ²ªG

CALC ªº²Ä¤G¶¥¬q¬O­pºâ¡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 ¶}©l­pºâ¨Ï¥ÎªÌ©Ò¿é¤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¡C­Y¬°¼Æ­È¡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¸¹¡B­t¸¹¡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¬O­pºâ«á§Ç¹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¬O­pºâ®É¶·¨Ì¾Ú¦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¥u­n§â¹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

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)