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 |
|
tthsqe 23 Jul 2013, 17:43
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. |
|||
23 Jul 2013, 17:43 |
|
Roman 23 Jul 2013, 18:07
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 |
|||
23 Jul 2013, 18:07 |
|
tthsqe 23 Jul 2013, 20:59
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 |
|||
23 Jul 2013, 20:59 |
|
Roman 24 Jul 2013, 07:37
tthsqe
Thanks ! But you code not compiling ! Fasm(ver 1.69.03) error mov edi,Code ! (Fasm write "Invalid operand") |
|||
24 Jul 2013, 07:37 |
|
MIHIP 24 Jul 2013, 07:49
Roman wrote: tthsqe Помогает 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 |
|||
24 Jul 2013, 07:49 |
|
MIHIP 24 Jul 2013, 07:55
Получается?
|
|||
24 Jul 2013, 07:55 |
|
Roman 24 Jul 2013, 07:58
MIHIP
Да получилось. Компилиться. И вчем прикол? Что в Casm такого (в отличии FASM-a) что он скомпилил этот код? |
|||
24 Jul 2013, 07:58 |
|
Roman 24 Jul 2013, 08:10
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 |
|||
24 Jul 2013, 08:10 |
|
MIHIP 24 Jul 2013, 09:38
Roman wrote: MIHIP Отличие в том, что он сначала смотрит весь код, потом ищет INCLUDE файлы (example is 'WIN32AX.INC'), потом уже в CASMW.INI заглядывает. |
|||
24 Jul 2013, 09:38 |
|
Roman 24 Jul 2013, 10:54
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:
|
||||||||||
24 Jul 2013, 10:54 |
|
tthsqe 24 Jul 2013, 20:18
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. |
|||
24 Jul 2013, 20:18 |
|
Roman 25 Jul 2013, 11:12
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:
|
||||||||||
25 Jul 2013, 11:12 |
|
tthsqe 25 Jul 2013, 13:16
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. |
|||
25 Jul 2013, 13:16 |
|
tthsqe 25 Jul 2013, 13:21
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 |
|||
25 Jul 2013, 13:21 |
|
dogman 25 Jul 2013, 14:03
This is very interesting. Maybe you can create a VM stack machine and then your code will be efficient and easier.
|
|||
25 Jul 2013, 14:03 |
|
Roman 25 Jul 2013, 15:57
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. |
|||
25 Jul 2013, 15:57 |
|
dogman 25 Jul 2013, 16:33
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. |
|||
25 Jul 2013, 16:33 |
|
tthsqe 25 Jul 2013, 18:06
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. |
|||
25 Jul 2013, 18:06 |
|
dogman 25 Jul 2013, 18:31
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. 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! |
|||
25 Jul 2013, 18:31 |
|
Goto page 1, 2 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.