flat assembler
Message board for the users of flat assembler.

Index > Main > Convert text to SSE2 code ! Breaking your brain :)

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
Roman



Joined: 21 Apr 2012
Posts: 815
Roman
In txt file we have this: 10.0+17.0/(1.0+4.0*4.0)*2.0+5.0
We load this txt file and then generated SSE2 commands that solve the example !

По русски:
У нас есть текстовый файл в нем пример вот такой: 10.0+17.0/(1.0+4.0*4.0)*2.0+5.0

Первое мы загружаем текстовый файл с этим примером.
Второе генерируем (по определенному адресу памяти) SSE2 код который решает данный пример (10.0+17.0/(1.0+4.0*4.0)*2.0+5.0)

Мозг сломать можно !
Please help !
Post 23 Jul 2013, 16:30
View user's profile Send private message Reply with quote
tthsqe



Joined: 20 May 2009
Posts: 730
tthsqe
So you are wanting to evaluate expressions?
For any fixed register count, there are always some expressions that cannot be evaluated. So, you will have to use the stack in your generated code.
You should try to solve this problem on your own, so I will just give you some hints:
- I think it will be easier to process the txt file with an actual program rather than fasm's macros
- You can parse simple expressions by maintaining two stacks: one for the numbers, the other for the operators
Example output code:
Code:
-1+2*(3+4)-5
; let's push the value of the expression onto the stack
push dword 1
unary neg
push dword 2
push dword 3
push dword 4
binary add
binary imul
binary add
push dword 5
binary sub

macro binary fxn {
 pop  ebx
 pop  eax
 fxn  eax,ebx
 push eax
}

macro unary fxn {
 fxn [esp]
}     

So you can see that the numbers are pushed by the same order that they appear in the expression. If you are having trouble with the operators, I could help some more after you think about it.
Post 23 Jul 2013, 17:43
View user's profile Send private message Reply with quote
Roman



Joined: 21 Apr 2012
Posts: 815
Roman
tthsqe
I'm talking about the real generation.
We compiled exe file programm.
And this program load txt file and create SSE2 code.
It can be said as a mathematical script

По русски:
Я делаю скрипт. Тоесть будет екзешник который загружает текстовый файл в котором текстовый пример и генерирует SSE2 код решающий данный пример. Этот SSE2 код выполняеться и выдает результат в виде MessageBox
Post 23 Jul 2013, 18:07
View user's profile Send private message Reply with quote
tthsqe



Joined: 20 May 2009
Posts: 730
tthsqe
Here is stripped-down version of something I had previously written.
It evaluates the expression by writing your SSE code to the label "Code" in the program. Have fun! I hope it doesn't break your brain....
Code:
format PE GUI 4.0
entry Start

include 'win32ax.inc'

IDI_MAIN        = 17
ID_DLGMAIN      = 37
ID_EXPRESSION   = 39
ID_RESULT       = 200
SUCCESS     = 0
EVAL_ERROR  = 1

section '.text' code readable writeable executable

Start:
        invoke  InitCommonControls
        invoke  GetModuleHandle,NULL
        invoke  DialogBoxParam,eax,ID_DLGMAIN,NULL,DlgProc,NULL
        invoke  ExitProcess,0

proc DlgProc,.hDlg,.uMsg,.wParam,.lParam
        push    ebx esi edi
        xor     ebx,ebx
        mov     eax,[.uMsg]
        mov     esi,[.hDlg]
        cmp     eax, WM_COMMAND
        je      .wmcommand
        cmp     eax, WM_CLOSE
        je      .wmclose
        cmp     eax, WM_INITDIALOG
        je      .wminitdialog
 .default:
        xor     eax, eax
        jmp     .return
 .wmcommand:
        movzx   edx, word[.wParam+2]
        movzx   eax, word[.wParam]
        cmp     eax, ID_EXPRESSION
        jne     .default
        cmp     edx, EN_CHANGE
        jne     .default
 .edit_changed:
                     invoke  SendDlgItemMessage,[.hDlg],ID_EXPRESSION,WM_GETTEXT,1023,InputString
                       push  ebp
                       call  ProcessInput
                        pop  ebp
                        mov  ebx,0x80C000

                        cmp  eax,EVAL_ERROR
                        mov  ecx,0x4000C0
                      cmove  ebx,ecx

                     invoke  SetDlgItemText,[.hDlg],ID_RESULT,ResultString

                        mov  dword[rc.left],1
                        mov  dword[rc.right],382
                        mov  dword[rc.top],1
                        mov  dword[rc.bottom],15
                     invoke  MapDialogRect,[.hDlg],rc

                     invoke  InvalidateRect,[.hDlg],NULL,FALSE
                     invoke  BeginPaint,[.hDlg],ps
                        mov  edi,eax
                     invoke  CreatePen,PS_SOLID,0,ebx
                        mov  ebx,eax
                     invoke  SelectObject,edi,ebx
                        mov  esi,eax
                     invoke  Rectangle,edi,[rc.left],[rc.top],[rc.right],[rc.bottom]
                     invoke  SelectObject,edi,esi
                     invoke  DeleteObject,ebx
                     invoke  EndPaint,[.hDlg],ps
                        jmp  .default
 .wmclose:
        invoke  EndDialog, esi, 0
        jmp     .default
 .wminitdialog:
        invoke  SendDlgItemMessage, esi, ID_EXPRESSION, EM_LIMITTEXT, 1022, 0
 .processed:
        xor     eax, eax
        inc     eax
 .return:
        pop     edi esi ebx
        ret
endp


SyntaxError_Uknown:
EvalError:              mov  esp,dword[espSave]
                        mov  eax,EVAL_ERROR
                        ret


FromInfix:   ; eax: input precedence
                        mov  edx,1
                        cmp  dword[ebp+4],1
                         je  .unary
                        cmp  ecx,eax
                        jbe  .ret
                 .1:    add  edx,1
                        cmp  ecx,dword[ebp+8]
                        jne  .unary
                        cmp  dword[ebp+8+4*1],1
                         je  .unary
                        add  ebp,8
                        jmp  .1
        .unary:         add  ebp,8
                       push  eax
                       call  ecx
                        pop  eax
        .entry:         mov  ecx,dword[ebp+4*0]
                        cmp  ecx,127
                         ja  FromInfix
        .ret:           ret


ProcessInput:         fldcw  word[fpcw_Prec64]

Parse:

NUMBER    = 0x00000001
PREFIX    = 0x00000002
INFIX     = 0x00000004
LEFT_PAR  = 0x00000040
RIGHT_PAR = 0x00000080
ENDER     = 0x00000200
UNARY     = 0x80000000

                        mov  dword[espSave],esp
                        lea  ebp,[esp-8]
                        mov  esi,InputString
                        mov  edi,Code
                        xor  eax,eax
                        mov  [ebp+0],eax
                        mov  [ebp+4],eax
                        sub  esp,1024
                        mov  ebx,NUMBER+PREFIX+INFIX+LEFT_PAR+UNARY
.Read:                  xor  edx,edx
.ReadChar:            lodsb
                        and  eax,0x07F
                        jmp  dword[DigitStringJTable+4*eax]
.Symbol:                cmp  dl,1
                         je  lex_Number
                        jmp  dword[SymbolJTable+4*eax]

.Dot:                   cmp  dl,1
                         jb  EvalError
                        bts  ebx,30
                         jc  EvalError
                        jmp  .ReadChar

.Letter:                jmp  EvalError

.Digit:                 cmp  dl,1
                         jb  .StartNumber
        .ContNumber:     bt  ebx,30
                        adc  dword[DigitsAfterDot],0
                        sub  eax,'0'
                       push  eax
                       fild  dword[InputBase]
                      fmulp  st1,st0
                       fild  dword[esp]
                      faddp  st1,st0
                        pop  eax
                        jmp  .ReadChar
        .StartNumber:   sub  eax,'0'
                        mov  dword[DigitsAfterDot],0
                        btr  ebx,30
                       push  eax
                       fild  dword[esp]
                        pop  eax
                        mov  edx,1
                        jmp  .ReadChar

lex_Number:             sub  esi,1
                         bt  ebx,0
                        jnc  EvalError


                        mov  ecx,[DigitsAfterDot]
                       fld1
                       fild  dword[InputBase]
                       test  ecx,ecx
                         jz  .w3
              .w1:      shr  ecx,1
                        jnc  .w2
                       fmul  st1,st0
              .w2:     test  ecx,ecx
                         jz  .w3
                       fmul  st0,st0
                        jmp  .w1
              .w3:     fstp  st0
                      fdivp  st1,st0
                       call  Fxn_Number
                        mov  ebx,INFIX+RIGHT_PAR+ENDER
                        jmp  Parse.Read

lex_plus:               mov  eax,Fxn_Plus
                        jmp  lex_Infix
lex_minus:              mov  eax,Fxn_Minus
                        jmp  lex_Infix
lex_times:              mov  eax,Fxn_Times
                        jmp  lex_Infix
lex_divide:             mov  eax,Fxn_Divide
                        jmp  lex_Infix
lex_Infix:               bt  ebx,2
                        jnc  EvalError
                         bt  ebx,31
                         jc  .Unary
                       call  FromInfix.entry
                        mov  ebx,NUMBER+PREFIX+INFIX+LEFT_PAR+UNARY
                        sub  ebp,8
                        mov  dword[ebp+4*0],eax
                        mov  dword[ebp+4*1],0
                        jmp  Parse.Read
          .Unary:       mov  ebx,NUMBER+PREFIX+INFIX+LEFT_PAR+UNARY
                        sub  ebp,8
                        mov  dword[ebp+4*0],eax
                        mov  dword[ebp+4*1],1
                        jmp  Parse.Read
lex_OpenPar:             bt  ebx,6
                        jnc  EvalError
                        mov  ebx,NUMBER+PREFIX+INFIX+LEFT_PAR+UNARY
                        sub  ebp,8
                        mov  dword[ebp+4*0],"("
                        jmp  Parse.Read
lex_ClosePar:            bt  ebx,7
                        jnc  EvalError
                        xor  eax,eax
                       call  FromInfix.entry
                        cmp  dword[ebp],"("
                        jne  EvalError
                        mov  ebx,INFIX+RIGHT_PAR+ENDER
                        add  ebp,8
                        jmp  Parse.Read
lex_Null:                bt  ebx,9
                        jnc  EvalError
                        xor  eax,eax
                       call  FromInfix.entry
                        cmp  dword[ebp],0
                        jne  EvalError

                       call  Fxn_Ret
                        mov  esp,[espSave]

; evaluate expression here
                       call  Code
                        sub  esp,8
                      movsd  qword[esp],xmm0
                       push  FormatString
                       push  ResultString
                       call  [sprintf]
                        add  esp,16
                        mov  dword[ResultString+eax],0
                        mov  eax,SUCCESS
                        ret


Fxn_Ret:               push  esi
                        lea  esi,[.1]
                        mov  ecx,.2-.1
                  rep movsb
                        pop  esi
                        ret

             .1:      movsd  xmm0,[esp]
                        add  esp,8
                        ret
             .2:

Fxn_Number:             sub  esp,8
                       fstp  qword[esp]
                        mov  al,0x68
                      stosb
                        mov  eax,[esp+4]
                      stosd
                        mov  al,0x68
                      stosb
                        mov  eax,[esp+0]
                      stosd
                        add  esp,8
                        ret


Fxn_Plus:               sub  edx,1
                         jb  EvalError
                         je  .unary
                       push  edx
                        mov  eax,0x84100FF2
                      stosd
                        mov  al,0x24
                      stosb
                        lea  eax,[edx*8]
                      stosd
                 @@:    sub  edx,1
                        mov  eax,0x84580FF2
                      stosd
                        mov  al,0x24
                      stosb
                        lea  eax,[edx*8]
                      stosd
                        jnz  @b
                        mov  ax,0xC481
                      stosw
                        pop  eax
                        shl  eax,3
                      stosd
                        mov  eax,0x04110FF2
                      stosd
                        mov  al,0xE4
                      stosb
                 .unary:
                        ret

Fxn_Minus:              sub  edx,1
                         jb  EvalError
                         je  .unary
                       push  edx
                        mov  eax,0x84100FF2
                      stosd
                        mov  al,0x24
                      stosb
                        lea  eax,[edx*8]
                      stosd
                 @@:    sub  edx,1
                        mov  eax,0x845C0FF2
                      stosd
                        mov  al,0x24
                      stosb
                        lea  eax,[edx*8]
                      stosd
                        jnz  @b
                        mov  ax,0xC481
                      stosw
                        pop  eax
                        shl  eax,3
                      stosd
                        mov  eax,0x04110FF2
                      stosd
                        mov  al,0xE4
                      stosb
                        ret

                 .unary:
                       push  esi
                        lea  esi,[.1]
                        mov  ecx,.2-.1
                  rep movsb
                        pop  esi
                        ret

             .1:      xorps  xmm0,xmm0
                      subsd  xmm0,[esp]
                      movsd  [esp],xmm0
             .2:

Fxn_Times:              sub  edx,1
                         jb  EvalError
                         je  .unary
                       push  edx
                        mov  eax,0x84100FF2
                      stosd
                        mov  al,0x24
                      stosb
                        lea  eax,[edx*8]
                      stosd
                 @@:    sub  edx,1
                        mov  eax,0x84590FF2
                      stosd
                        mov  al,0x24
                      stosb
                        lea  eax,[edx*8]
                      stosd
                        jnz  @b
                        mov  ax,0xC481
                      stosw
                        pop  eax
                        shl  eax,3
                      stosd
                        mov  eax,0x04110FF2
                      stosd
                        mov  al,0xE4
                      stosb
                 .unary:
                        ret

Fxn_Divide:             sub  edx,1
                         jb  EvalError
                         je  .unary
                       push  edx
                        mov  eax,0x84100FF2
                      stosd
                        mov  al,0x24
                      stosb
                        lea  eax,[edx*8]
                      stosd
                 @@:    sub  edx,1
                        mov  eax,0x845E0FF2
                      stosd
                        mov  al,0x24
                      stosb
                        lea  eax,[edx*8]
                      stosd
                        jnz  @b
                        mov  ax,0xC481
                      stosw
                        pop  eax
                        shl  eax,3
                      stosd
                        mov  eax,0x04110FF2
                      stosd
                        mov  al,0xE4
                      stosb
                        ret

                 .unary:
                       push  esi
                        lea  esi,[.1]
                        mov  ecx,.2-.1
                  rep movsb
                        pop  esi
                        ret

             .1:        mov  eax,1
                   cvtsi2sd  xmm0,eax
                      divsd  xmm0,[esp]
                      movsd  [esp],xmm0
             .2:





Code:
rb 10000



section '.data' data readable writeable

align 16

DigitStringJTable:
dd Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  \
   Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  \
   Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  \
   Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  \
   Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,\
   Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Dot,     Parse.Symbol,\
   Parse.Digit,   Parse.Digit,   Parse.Digit,   Parse.Digit,   Parse.Digit,   Parse.Digit,   Parse.Digit,   Parse.Digit,\
   Parse.Digit,   Parse.Digit,   Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,\
   Parse.Symbol,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,\
   Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,\
   Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,\
   Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,\
   Parse.Symbol,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,\
   Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,\
   Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,\
   Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol
SymbolJTable:
dd lex_Null,          Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    \
   Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    \
   Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    \
   Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    \
   Parse.ReadChar,    SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,\
   lex_OpenPar,       lex_ClosePar,      lex_times,         lex_plus,          SyntaxError_Uknown,lex_minus,         SyntaxError_Uknown,lex_divide,        \
   SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,\
   SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,\
   SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,\
   SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,\
   SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,\
   SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,\
   SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,\
   SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,\
   SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,\
   SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,Parse.ReadChar

align 4
  InputBase dd 10

align 2
  fpcw_Prec64: dw 0x037F

align 1
  FormatString db '%0.15g',0

align 4
  ps             PAINTSTRUCT
  rc             RECT
  DigitsAfterDot dd ?
  espSave        dd ?
  InputString    rb 1024
  ResultString   rb 256




section '.idata' import data readable writeable

 library kernel32,'KERNEL32.DLL',\
         user32,'USER32.DLL',\
         gdi32,'GDI32.DLL',\
         comctl32,'COMCTL32.DLL',\
         msvcrt,'MSVCRT.DLL'

include 'api/kernel32.inc'
include 'api/user32.inc'
include 'api/gdi32.inc'

 import msvcrt,\
        sprintf,'sprintf'

 import  comctl32,\
         InitCommonControls,'InitCommonControls'


section '.rsrc' resource data readable

  directory RT_DIALOG,dialogs,\
            24,manifest

  resource dialogs,\
           ID_DLGMAIN,LANG_ENGLISH+SUBLANG_DEFAULT,calculator


  resource manifest,\
           1,LANG_ENGLISH+SUBLANG_DEFAULT,manifest_data

  dialog calculator,'SMC calculator',10,10,384,40,DS_CENTER+DS_MODALFRAME+WS_SYSMENU+WS_MINIMIZEBOX,0,0;ID_MENUMAIN
    dialogitem 'EDIT','',ID_EXPRESSION,2,2,380,12,WS_VISIBLE+WS_TABSTOP+WS_BORDER+ES_AUTOHSCROLL
    dialogitem 'EDIT','',ID_RESULT ,2,16,256,12,WS_VISIBLE+WS_BORDER+WS_TABSTOP+ES_READONLY+ES_AUTOHSCROLL
  enddialog


  resdata manifest_data
       db "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>",13,10
       db "<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>",13,10
       db "<dependency>",13,10
       db "<dependentAssembly>",13,10
       db "<assemblyIdentity type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*' />",13,10
       db "</dependentAssembly>",13,10
       db "</dependency>",13,10
       db "</assembly>",13,10
  endres    
Post 23 Jul 2013, 20:59
View user's profile Send private message Reply with quote
Roman



Joined: 21 Apr 2012
Posts: 815
Roman
tthsqe
Thanks !
But you code not compiling !
Fasm(ver 1.69.03) error mov edi,Code ! (Fasm write "Invalid operand")
Post 24 Jul 2013, 07:37
View user's profile Send private message Reply with quote
MIHIP



Joined: 14 Feb 2013
Posts: 130
MIHIP
Roman wrote:
tthsqe
Thanks !
But you code not compiling !
Fasm(ver 1.69.03) error mov edi,Code ! (Fasm write "Invalid operand")

Very Happy Помогает Casm! У меня стоит Casm, всё компилируется. Короче - скачай Casm, установи в C:\Program Files\Casm. Затем в C:\Program Files\Casm создай файл Test.asm и запусти CASMW.EXE. Потом измени файл Test.asm в CASMW.EXE на этот код:
Code:
format PE GUI 4.0
entry Start 

include 'win32ax.inc' 

IDI_MAIN        = 17 
ID_DLGMAIN      = 37 
ID_EXPRESSION   = 39 
ID_RESULT       = 200 
SUCCESS     = 0 
EVAL_ERROR  = 1 

section '.text' code readable writeable executable 

Start: 
        invoke  InitCommonControls 
        invoke  GetModuleHandle,NULL 
        invoke  DialogBoxParam,eax,ID_DLGMAIN,NULL,DlgProc,NULL 
        invoke  ExitProcess,0 

proc DlgProc,.hDlg,.uMsg,.wParam,.lParam 
        push    ebx esi edi 
        xor     ebx,ebx 
        mov     eax,[.uMsg] 
        mov     esi,[.hDlg] 
        cmp     eax, WM_COMMAND 
        je      .wmcommand 
        cmp     eax, WM_CLOSE 
        je      .wmclose 
        cmp     eax, WM_INITDIALOG 
        je      .wminitdialog 
 .default: 
        xor     eax, eax 
        jmp     .return 
 .wmcommand: 
        movzx   edx, word[.wParam+2] 
        movzx   eax, word[.wParam] 
        cmp     eax, ID_EXPRESSION 
        jne     .default 
        cmp     edx, EN_CHANGE 
        jne     .default 
 .edit_changed: 
                     invoke  SendDlgItemMessage,[.hDlg],ID_EXPRESSION,WM_GETTEXT,1023,InputString 
                       push  ebp 
                       call  ProcessInput 
                        pop  ebp 
                        mov  ebx,0x80C000 

                        cmp  eax,EVAL_ERROR 
                        mov  ecx,0x4000C0 
                      cmove  ebx,ecx 

                     invoke  SetDlgItemText,[.hDlg],ID_RESULT,ResultString 

                        mov  dword[rc.left],1 
                        mov  dword[rc.right],382 
                        mov  dword[rc.top],1 
                        mov  dword[rc.bottom],15 
                     invoke  MapDialogRect,[.hDlg],rc 

                     invoke  InvalidateRect,[.hDlg],NULL,FALSE 
                     invoke  BeginPaint,[.hDlg],ps 
                        mov  edi,eax 
                     invoke  CreatePen,PS_SOLID,0,ebx 
                        mov  ebx,eax 
                     invoke  SelectObject,edi,ebx 
                        mov  esi,eax 
                     invoke  Rectangle,edi,[rc.left],[rc.top],[rc.right],[rc.bottom] 
                     invoke  SelectObject,edi,esi 
                     invoke  DeleteObject,ebx 
                     invoke  EndPaint,[.hDlg],ps 
                        jmp  .default 
 .wmclose: 
        invoke  EndDialog, esi, 0 
        jmp     .default 
 .wminitdialog: 
        invoke  SendDlgItemMessage, esi, ID_EXPRESSION, EM_LIMITTEXT, 1022, 0 
 .processed: 
        xor     eax, eax 
        inc     eax 
 .return: 
        pop     edi esi ebx 
        ret 
endp 


SyntaxError_Uknown: 
EvalError:              mov  esp,dword[espSave] 
                        mov  eax,EVAL_ERROR 
                        ret 


FromInfix:   ; eax: input precedence 
                        mov  edx,1 
                        cmp  dword[ebp+4],1 
                         je  .unary 
                        cmp  ecx,eax 
                        jbe  .ret 
                 .1:    add  edx,1 
                        cmp  ecx,dword[ebp+8] 
                        jne  .unary 
                        cmp  dword[ebp+8+4*1],1 
                         je  .unary 
                        add  ebp,8 
                        jmp  .1 
        .unary:         add  ebp,8 
                       push  eax 
                       call  ecx 
                        pop  eax 
        .entry:         mov  ecx,dword[ebp+4*0] 
                        cmp  ecx,127 
                         ja  FromInfix 
        .ret:           ret 


ProcessInput:         fldcw  word[fpcw_Prec64] 

Parse: 

NUMBER    = 0x00000001 
PREFIX    = 0x00000002 
INFIX     = 0x00000004 
LEFT_PAR  = 0x00000040 
RIGHT_PAR = 0x00000080 
ENDER     = 0x00000200 
UNARY     = 0x80000000 

                        mov  dword[espSave],esp 
                        lea  ebp,[esp-8] 
                        mov  esi,InputString 
                        mov  edi,Code 
                        xor  eax,eax 
                        mov  [ebp+0],eax 
                        mov  [ebp+4],eax 
                        sub  esp,1024 
                        mov  ebx,NUMBER+PREFIX+INFIX+LEFT_PAR+UNARY 
.Read:                  xor  edx,edx 
.ReadChar:            lodsb 
                        and  eax,0x07F 
                        jmp  dword[DigitStringJTable+4*eax] 
.Symbol:                cmp  dl,1 
                         je  lex_Number 
                        jmp  dword[SymbolJTable+4*eax] 

.Dot:                   cmp  dl,1 
                         jb  EvalError 
                        bts  ebx,30 
                         jc  EvalError 
                        jmp  .ReadChar 

.Letter:                jmp  EvalError 

.Digit:                 cmp  dl,1 
                         jb  .StartNumber 
        .ContNumber:     bt  ebx,30 
                        adc  dword[DigitsAfterDot],0 
                        sub  eax,'0' 
                       push  eax 
                       fild  dword[InputBase] 
                      fmulp  st1,st0 
                       fild  dword[esp] 
                      faddp  st1,st0 
                        pop  eax 
                        jmp  .ReadChar 
        .StartNumber:   sub  eax,'0' 
                        mov  dword[DigitsAfterDot],0 
                        btr  ebx,30 
                       push  eax 
                       fild  dword[esp] 
                        pop  eax 
                        mov  edx,1 
                        jmp  .ReadChar 

lex_Number:             sub  esi,1 
                         bt  ebx,0 
                        jnc  EvalError 


                        mov  ecx,[DigitsAfterDot] 
                       fld1 
                       fild  dword[InputBase] 
                       test  ecx,ecx 
                         jz  .w3 
              .w1:      shr  ecx,1 
                        jnc  .w2 
                       fmul  st1,st0 
              .w2:     test  ecx,ecx 
                         jz  .w3 
                       fmul  st0,st0 
                        jmp  .w1 
              .w3:     fstp  st0 
                      fdivp  st1,st0 
                       call  Fxn_Number 
                        mov  ebx,INFIX+RIGHT_PAR+ENDER 
                        jmp  Parse.Read 

lex_plus:               mov  eax,Fxn_Plus 
                        jmp  lex_Infix 
lex_minus:              mov  eax,Fxn_Minus 
                        jmp  lex_Infix 
lex_times:              mov  eax,Fxn_Times 
                        jmp  lex_Infix 
lex_divide:             mov  eax,Fxn_Divide 
                        jmp  lex_Infix 
lex_Infix:               bt  ebx,2 
                        jnc  EvalError 
                         bt  ebx,31 
                         jc  .Unary 
                       call  FromInfix.entry 
                        mov  ebx,NUMBER+PREFIX+INFIX+LEFT_PAR+UNARY 
                        sub  ebp,8 
                        mov  dword[ebp+4*0],eax 
                        mov  dword[ebp+4*1],0 
                        jmp  Parse.Read 
          .Unary:       mov  ebx,NUMBER+PREFIX+INFIX+LEFT_PAR+UNARY 
                        sub  ebp,8 
                        mov  dword[ebp+4*0],eax 
                        mov  dword[ebp+4*1],1 
                        jmp  Parse.Read 
lex_OpenPar:             bt  ebx,6 
                        jnc  EvalError 
                        mov  ebx,NUMBER+PREFIX+INFIX+LEFT_PAR+UNARY 
                        sub  ebp,8 
                        mov  dword[ebp+4*0],"(" 
                        jmp  Parse.Read 
lex_ClosePar:            bt  ebx,7 
                        jnc  EvalError 
                        xor  eax,eax 
                       call  FromInfix.entry 
                        cmp  dword[ebp],"(" 
                        jne  EvalError 
                        mov  ebx,INFIX+RIGHT_PAR+ENDER 
                        add  ebp,8 
                        jmp  Parse.Read 
lex_Null:                bt  ebx,9 
                        jnc  EvalError 
                        xor  eax,eax 
                       call  FromInfix.entry 
                        cmp  dword[ebp],0 
                        jne  EvalError 

                       call  Fxn_Ret 
                        mov  esp,[espSave] 

; evaluate expression here 
                       call  Code 
                        sub  esp,8 
                      movsd  qword[esp],xmm0 
                       push  FormatString 
                       push  ResultString 
                       call  [sprintf] 
                        add  esp,16 
                        mov  dword[ResultString+eax],0 
                        mov  eax,SUCCESS 
                        ret 


Fxn_Ret:               push  esi 
                        lea  esi,[.1] 
                        mov  ecx,.2-.1 
                  rep movsb 
                        pop  esi 
                        ret 

             .1:      movsd  xmm0,[esp] 
                        add  esp,8 
                        ret 
             .2: 

Fxn_Number:             sub  esp,8 
                       fstp  qword[esp] 
                        mov  al,0x68 
                      stosb 
                        mov  eax,[esp+4] 
                      stosd 
                        mov  al,0x68 
                      stosb 
                        mov  eax,[esp+0] 
                      stosd 
                        add  esp,8 
                        ret 


Fxn_Plus:               sub  edx,1 
                         jb  EvalError 
                         je  .unary 
                       push  edx 
                        mov  eax,0x84100FF2 
                      stosd 
                        mov  al,0x24 
                      stosb 
                        lea  eax,[edx*8] 
                      stosd 
                 @@:    sub  edx,1 
                        mov  eax,0x84580FF2 
                      stosd 
                        mov  al,0x24 
                      stosb 
                        lea  eax,[edx*8] 
                      stosd 
                        jnz  @b 
                        mov  ax,0xC481 
                      stosw 
                        pop  eax 
                        shl  eax,3 
                      stosd 
                        mov  eax,0x04110FF2 
                      stosd 
                        mov  al,0xE4 
                      stosb 
                 .unary: 
                        ret 

Fxn_Minus:              sub  edx,1 
                         jb  EvalError 
                         je  .unary 
                       push  edx 
                        mov  eax,0x84100FF2 
                      stosd 
                        mov  al,0x24 
                      stosb 
                        lea  eax,[edx*8] 
                      stosd 
                 @@:    sub  edx,1 
                        mov  eax,0x845C0FF2 
                      stosd 
                        mov  al,0x24 
                      stosb 
                        lea  eax,[edx*8] 
                      stosd 
                        jnz  @b 
                        mov  ax,0xC481 
                      stosw 
                        pop  eax 
                        shl  eax,3 
                      stosd 
                        mov  eax,0x04110FF2 
                      stosd 
                        mov  al,0xE4 
                      stosb 
                        ret 

                 .unary: 
                       push  esi 
                        lea  esi,[.1] 
                        mov  ecx,.2-.1 
                  rep movsb 
                        pop  esi 
                        ret 

             .1:      xorps  xmm0,xmm0 
                      subsd  xmm0,[esp] 
                      movsd  [esp],xmm0 
             .2: 

Fxn_Times:              sub  edx,1 
                         jb  EvalError 
                         je  .unary 
                       push  edx 
                        mov  eax,0x84100FF2 
                      stosd 
                        mov  al,0x24 
                      stosb 
                        lea  eax,[edx*8] 
                      stosd 
                 @@:    sub  edx,1 
                        mov  eax,0x84590FF2 
                      stosd 
                        mov  al,0x24 
                      stosb 
                        lea  eax,[edx*8] 
                      stosd 
                        jnz  @b 
                        mov  ax,0xC481 
                      stosw 
                        pop  eax 
                        shl  eax,3 
                      stosd 
                        mov  eax,0x04110FF2 
                      stosd 
                        mov  al,0xE4 
                      stosb 
                 .unary: 
                        ret 

Fxn_Divide:             sub  edx,1 
                         jb  EvalError 
                         je  .unary 
                       push  edx 
                        mov  eax,0x84100FF2 
                      stosd 
                        mov  al,0x24 
                      stosb 
                        lea  eax,[edx*8] 
                      stosd 
                 @@:    sub  edx,1 
                        mov  eax,0x845E0FF2 
                      stosd 
                        mov  al,0x24 
                      stosb 
                        lea  eax,[edx*8] 
                      stosd 
                        jnz  @b 
                        mov  ax,0xC481 
                      stosw 
                        pop  eax 
                        shl  eax,3 
                      stosd 
                        mov  eax,0x04110FF2 
                      stosd 
                        mov  al,0xE4 
                      stosb 
                        ret 

                 .unary: 
                       push  esi 
                        lea  esi,[.1] 
                        mov  ecx,.2-.1 
                  rep movsb 
                        pop  esi 
                        ret 

             .1:        mov  eax,1 
                   cvtsi2sd  xmm0,eax 
                      divsd  xmm0,[esp] 
                      movsd  [esp],xmm0 
             .2: 





Code: 
rb 10000 



section '.data' data readable writeable 

align 16 

DigitStringJTable: 
dd Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  \ 
   Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  \ 
   Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  \ 
   Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  \ 
   Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,\ 
   Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Dot,     Parse.Symbol,\ 
   Parse.Digit,   Parse.Digit,   Parse.Digit,   Parse.Digit,   Parse.Digit,   Parse.Digit,   Parse.Digit,   Parse.Digit,\ 
   Parse.Digit,   Parse.Digit,   Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,\ 
   Parse.Symbol,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,\ 
   Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,\ 
   Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,\ 
   Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,\ 
   Parse.Symbol,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,\ 
   Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,\ 
   Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Letter,\ 
   Parse.Letter,  Parse.Letter,  Parse.Letter,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol,  Parse.Symbol 
SymbolJTable: 
dd lex_Null,          Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    \
   Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    \
   Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    \
   Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    Parse.ReadChar,    \
   Parse.ReadChar,    SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,\
   lex_OpenPar,       lex_ClosePar,      lex_times,         lex_plus,          SyntaxError_Uknown,lex_minus,         SyntaxError_Uknown,lex_divide,        \
   SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,\
   SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,\
   SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,\
   SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,\
   SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,\
   SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,\
   SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,\
   SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,\
   SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,\
   SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,SyntaxError_Uknown,Parse.ReadChar

align 4 
  InputBase dd 10 

align 2 
  fpcw_Prec64: dw 0x037F 

align 1 
  FormatString db '%0.15g',0 

align 4 
  ps             PAINTSTRUCT 
  rc             RECT 
  DigitsAfterDot dd ? 
  espSave        dd ? 
  InputString    rb 1024 
  ResultString   rb 256 




section '.idata' import data readable writeable 

 library kernel32,'KERNEL32.DLL',\ 
         user32,'USER32.DLL',\ 
         gdi32,'GDI32.DLL',\ 
         comctl32,'COMCTL32.DLL',\ 
         msvcrt,'MSVCRT.DLL' 

include 'api/kernel32.inc' 
include 'api/user32.inc' 
include 'api/gdi32.inc' 

 import msvcrt,\ 
        sprintf,'sprintf' 

 import  comctl32,\ 
         InitCommonControls,'InitCommonControls' 


section '.rsrc' resource data readable 

  directory RT_DIALOG,dialogs,\ 
            24,manifest 

  resource dialogs,\ 
           ID_DLGMAIN,LANG_ENGLISH+SUBLANG_DEFAULT,calculator 


  resource manifest,\ 
           1,LANG_ENGLISH+SUBLANG_DEFAULT,manifest_data 

  dialog calculator,'SMC calculator',10,10,384,40,DS_CENTER+DS_MODALFRAME+WS_SYSMENU+WS_MINIMIZEBOX,0,0;ID_MENUMAIN 
    dialogitem 'EDIT','',ID_EXPRESSION,2,2,380,12,WS_VISIBLE+WS_TABSTOP+WS_BORDER+ES_AUTOHSCROLL 
    dialogitem 'EDIT','',ID_RESULT ,2,16,256,12,WS_VISIBLE+WS_BORDER+WS_TABSTOP+ES_READONLY+ES_AUTOHSCROLL 
  enddialog 


  resdata manifest_data 
       db "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>",13,10 
       db "<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>",13,10 
       db "<dependency>",13,10 
       db "<dependentAssembly>",13,10 
       db "<assemblyIdentity type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*' />",13,10 
       db "</dependentAssembly>",13,10 
       db "</dependency>",13,10 
       db "</assembly>",13,10 
  endres    
. Нажми Run и всё! Готово! У меня работает. 1.23123123123123e+092 = 123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123123. Laughing . Так что Casm не бесполезный!!! Razz
Post 24 Jul 2013, 07:49
View user's profile Send private message Visit poster's website Reply with quote
MIHIP



Joined: 14 Feb 2013
Posts: 130
MIHIP
Получается? Rolling Eyes
Post 24 Jul 2013, 07:55
View user's profile Send private message Visit poster's website Reply with quote
Roman



Joined: 21 Apr 2012
Posts: 815
Roman
MIHIP
Да получилось. Компилиться.
И вчем прикол?
Что в Casm такого (в отличии FASM-a) что он скомпилил этот код?
Post 24 Jul 2013, 07:58
View user's profile Send private message Reply with quote
Roman



Joined: 21 Apr 2012
Posts: 815
Roman
tthsqe
Thanks dude. You're cool !
This example compiling in Fasm 1.71.11 !


Last edited by Roman on 24 Jul 2013, 08:19; edited 1 time in total
Post 24 Jul 2013, 08:10
View user's profile Send private message Reply with quote
MIHIP



Joined: 14 Feb 2013
Posts: 130
MIHIP
Roman wrote:
MIHIP
Да получилось. Компилиться.
И вчем прикол?
Что в Casm такого (в отличии FASM-a) что он скомпилил этот код?

Отличие в том, что он сначала смотрит весь код, потом ищет INCLUDE файлы (example is 'WIN32AX.INC'), потом уже в CASMW.INI заглядывает. Laughing
Post 24 Jul 2013, 09:38
View user's profile Send private message Visit poster's website Reply with quote
Roman



Joined: 21 Apr 2012
Posts: 815
Roman
tthsqe
You programm generated much more SSE2 commands than need for calculation this: 2+2/(1+4*4)/17

Code start from 0x004013E7 to 0x004014A8
I enclose a screen:


Description:
Filesize: 398.97 KB
Viewed: 7341 Time(s)

sse2.jpg


Post 24 Jul 2013, 10:54
View user's profile Send private message Reply with quote
tthsqe



Joined: 20 May 2009
Posts: 730
tthsqe
I agree - if you use only ONE register, there is a lot of data movement. Keep in mind that efficient register allocation is a reason why modern optimizing compilers are HUGE programs.
What kind of improvements are you expecting?
more complicated register allocation?
give some specifics suggestions for your example of
2+2/(1+4*4)/17
The algorithm that I chose above is probably the simplest possible, and has the fastest compilation time.
Post 24 Jul 2013, 20:18
View user's profile Send private message Reply with quote
Roman



Joined: 21 Apr 2012
Posts: 815
Roman
tthsqe
I understand that you've done a good job.
But like the result was close to hand code.

I understand the better code we can write only hands.

I do my parser.
My result.
Example 15.0/(8.0+4.0*2.0/2.0+3.0) = 1.0
If we look my SSE2 commands we see an extra instruction (i mean mov xmm1,xmm7)
My SSE2 code after calculation this example:


Description:
Filesize: 59.03 KB
Viewed: 7260 Time(s)

MySSE2.jpg


Post 25 Jul 2013, 11:12
View user's profile Send private message Reply with quote
tthsqe



Joined: 20 May 2009
Posts: 730
tthsqe
It looks like your parser is generating code that uses the MINIMUM number of registers, which is two for your example. Would you mind posting your parser?
In order to find the minimum register count, you have to make a few passes over the expression tree; the code that I posted is a single pass compiler.
The other problem is that the minimum register count could be greater than 8 (in this case, it is necessary that the number of numbers in the expression not less than 64). If the register count is greater than 8, than some spilling has to occur, and once things are spilled, your code generator will get messier.
Post 25 Jul 2013, 13:16
View user's profile Send private message Reply with quote
tthsqe



Joined: 20 May 2009
Posts: 730
tthsqe
you code for 15.0/(8.0+4.0*2.0/2.0+3.0) should be
Code:
xmm1 = 4
xmm1 *= 2
xmm1 /= 2
xmm1 += 8
xmm1 += 3
xmm0 = 15
xmm0 /= xmm1    
Post 25 Jul 2013, 13:21
View user's profile Send private message Reply with quote
dogman



Joined: 18 Jul 2013
Posts: 114
dogman
This is very interesting. Maybe you can create a VM stack machine and then your code will be efficient and easier.
Post 25 Jul 2013, 14:03
View user's profile Send private message Reply with quote
Roman



Joined: 21 Apr 2012
Posts: 815
Roman
tthsqe
You're right my parser working with a not very large expressions.
Very hard write parser working with a large expressions.
I look forward to the solution of such examples 4.0+2.0*5.0*(1.0+5.0+3.0*3.0/9.0+2.0*8.0)/4.0/2.0+11.0 is not over
That's enough to combine more complex expressions.

Unfortunately until my parser has bugs. And now i`m working on my parser.
tthsqe
I liked your example. He works good, but generated much more SSE2 commands and PUSH than need for calculation expressions.
Post 25 Jul 2013, 15:57
View user's profile Send private message Reply with quote
dogman



Joined: 18 Jul 2013
Posts: 114
dogman
I don't understand why it's harder to parse larger expressions. Are you using the generalized
https://en.wikipedia.org/wiki/Shunting-yard_algorithm

It works on expressions of any size. I looked many places for a decent description and this page seemed the best to me.
Post 25 Jul 2013, 16:33
View user's profile Send private message Reply with quote
tthsqe



Joined: 20 May 2009
Posts: 730
tthsqe
dogman, that link is simply for converting infix notation to postfix notation.
Ex: 1+2*3/(4+5) -> 1 2 3 * 4 5 + / +
This is exactly what my one pass compiler does, and roman didn't like it because it used only one register and the stack.
The postifix notation provides one with an expression tree.
I think then one needs two passes over this tree to produce code that uses minimum number of registers: one pass to determine minimum register count, and another pass to actually produce the code.
I'll give it a shot soon.
Post 25 Jul 2013, 18:06
View user's profile Send private message Reply with quote
dogman



Joined: 18 Jul 2013
Posts: 114
dogman
tthsqe wrote:
dogman, that link is simply for converting infix notation to postfix notation.


It is not only for converting from infix to postfix but also for evaluating it. Instead of outputting the postfix you use the stack and perform the operations when popping them off. At the end you get your result.

tthsqe wrote:
This is exactly what my one pass compiler does, and roman didn't like it because it used only one register and the stack.


Yes I know. But I think trying to compile one specific expression is not a generally useful piece of code. Isn't it more useful to be able to process any infix expression?

tthsqe wrote:
The postifix notation provides one with an expression tree.
I think then one needs two passes over this tree to produce code that uses minimum number of registers: one pass to determine minimum register count, and another pass to actually produce the code.
I'll give it a shot soon.


It's something I worked on recently (not in assembly though) so I was interested in this thread. As you said for an arbitrarily long expression you will run out of registers quickly. I don't see the point in this, it degenerates to nothing but an exercise in register allocation.

Compiling a constant expression is only an exercise and not very useful. It would be more useful if you create an evaluation engine and feed it infix. But maybe this is a theoretical exercise. Ok, sorry for the interruption. And don't forget to deal with operator precedence or your evaluation won't be correct.

_________________
Sources? Ahahaha! We don't need no stinkin' sources!
Post 25 Jul 2013, 18:31
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.