The MASM Forum

Projects => Rarely Used Projects => RosAsm => Topic started by: jj2007 on July 06, 2014, 06:22:51 PM

Title: RosAsm2Masm
Post by: jj2007 on July 06, 2014, 06:22:51 PM
Hi Guga,
I am studying RosAsm syntax with code extracted from the snapshot thread (http://masm32.com/board/index.php?topic=3373.0), see attachment.

What is the purpose of the varying number of dots in front of the If / ElseIf /EndIf instructions? And is the case of If / ElseIf /EndIf fixed?
Title: Re: RosAsm2Masm
Post by: guga on July 06, 2014, 09:44:35 PM
They are to identify where The If/Else/ElseIf/EndIf blocks are located (Nested If´s). They are called "non optimized jmps". Ie the assembler must now where to jump to, instead "guessing" (or making huge computations) to identify the final pointer.

For example:
..If eax < 6
   .If eax = 3
        mov ecx 5
   .Else
        mov ecx 2
   .End_If
..Else
     mov ecx 7
..End_If

Unfolded, it should be something like:

    CMP EAX 6 | JNB K1>>
        CMP EAX 3 | JNE J1>>
            mov ecx 5
        JMP J9>>
        J1:
            mov ecx 2
        J9:   
    JMP K9>>
    K1:
        mov ecx 7
    K9:

In red, if eax is smaller then 6 it will go to the next If series and check for eax 3 and other values
In red, if it is any other valuer bigger or equal then 6, ecx = 7

This macro set of If´s works more or less like a treeview :)
The macro set i use i basically allow no more then 4 or 5 nested if series. "....If" "...If" "..If" ".If" "If". This level of nesting Ifs are enough in the majority of the situations. (I rarely use 4 dots, btw)

Of course, you can avoid this usage and  simply use one single dot for the most "distant" If´s, from the menu "Compile + Optimize Jump Sizes", or use a newer If macro set. But, personally, i prefer this old macro style i regulary use


Btw, if you want to see what is inside the macros, all you have to do is right click upon one macro (For example..."Proc", "EndP", "If", "local", "structure" etc...) and you will move to the macro definition inside the source. The macros are all user made. There is no (or very few) rigid tokens to work with. The sytnax is Nasm based, the main difference is the macro set.

Or...you also can select a macro to be unfolded to see assembly code behind. To activate unfold there are 2 ways:



For the variables, macros and equates the difference is easy. They are all inside brackets. If what is inside contains no separator "|", then it is an equate. If it have a separator it is a macro, if it have a ":" the it is a global variable
[GUGA 1234] <--- equate/constant/immediate value
[GUGA | mov eax ebx] <--- macro
[GUGA: D$ 56] <---global variable Dword sized
[GUGA: 56] <---global variable Dword sized by default. When there is no type size defined
[GUGA: B$ 56] <---global variable Byte Sized
[GUGA: W$ 56] <---global variable Word Sized
[GUGA: T$ 56] <---global variable Tenbyte Sized
[GUGA: F$ 56] <---global variable Float32 sized
[GUGA: R$ 56] <---global variable Float64 sized
[GUGA: Q$ 56] <---global variable Quadword sized

And all Win Equates are defined with an "&" sign, such as "&WM_COMMAND"

Title: Re: RosAsm2Masm
Post by: jj2007 on July 08, 2014, 03:53:56 AM
Just for fun, attached a new version if RosAsm2Masm.
It expects a text file in the commandline; if there is no argument, RosAsmTest.asm is assumed. For the converted text, use Console Build All in qEditor. Here is an example:
TITLE CODE
_________________________________________________________________________

[IDD_MAINDIALOG 1000]

[IDC_OPEN 10]
[IDC_CLOSE 1]
[IDC_EXIT 2]
[IDC_TEXT 100]



[hInstance: D$ 0]
[CommandLine: D$ 0]

Main:

    call 'Kernel32.GetModuleHandleA' &NULL
    mov D$hInstance eax
    call 'kernel32.GetCommandLineA'
    mov D$CommandLine eax
    call 'USER32.DialogBoxParamA' D$hinstance, IDD_MAINDIALOG, &NULL, ScanHeaderFile, &NULL
    call 'kernel32.ExitProcess' eax

______________________________________________________________________________________________________________

; Tag Dialog 1000

[hEdit: D$ 0]

Proc ScanHeaderFile:
    Arguments @Adressee, @Message, @wParam, @lParam

     pushad

    ...If D@Message = &WM_COMMAND                  ; User action

        ..If D@wParam = IDC_EXIT;, D@wParam = M03_Exit  ; User clicks on upper right [X] or Exited through the menu
            call HeaderScanCleanUp D@Adressee
            call 'USER32.EndDialog' D@Adressee &NULL
        ..Else_If D@wParam = IDC_CLOSE

            call HeaderScanCleanUp D@Adressee

        ..End_If


    ...Else_If D@Message = &WM_INITDIALOG
        ;move D$hwnd D@Adressee
        call 'user32.SendMessageA' D@Adressee, &WM_SETTEXT, 0, {B$ "Processes view", 0}
        call 'user32.GetDlgItem' D@Adressee, IDC_TEXT | mov D$hEdit eax
        call 'USER32.SendMessageA' D$hEdit, &EM_SETLIMITTEXT, 0, 0 ; extends the text limit ot the edit control to 0-1
        call GetProcessList

    ...Else_If D@Message = &WM_CLOSE
         call HeaderScanCleanUp D@Adressee
         call 'USER32.EndDialog' D@Adressee &NULL

    ...Else
        popad | mov eax &FALSE | ExitP

    ...End_If

L9: popad | mov eax &TRUE

EndP

____________________________________________________________________________________

Proc HeaderScanCleanUp:
    Arguments @Adressee

    call 'USER32.SendDlgItemMessageA' D@Adressee, IDC_TEXT, &WM_SETTEXT, 0, &NULL

EndP

TITLE BeginProcess
__________________________________________________________________________________________________

[PROCESSENTRY32.dwSizeDis 0
PROCESSENTRY32.cntUsageDis 4
PROCESSENTRY32.th32ProcessIDDis 8
PROCESSENTRY32.th32DefaultHeapIDDis 12
PROCESSENTRY32.th32ModuleIDDis 16
PROCESSENTRY32.cntThreadsDis 20
PROCESSENTRY32.th32ParentProcessIDDis 24
PROCESSENTRY32.pcPriClassBaseDis 28
PROCESSENTRY32.dwFlagsDis 32
PROCESSENTRY32.szExeFileDis 36]

[Size_Of_PROCESSENTRY32 296]

Proc GetProcessList:
    Local @hSnapShot, @dwPriorityClass, @hProcess
    Structure @PROCESSENTRY32 296, @PROCESSENTRY32.dwSizeDis 0, @PROCESSENTRY32.cntUsageDis 4, @PROCESSENTRY32.th32ProcessIDDis 8,
                                   @PROCESSENTRY32.th32DefaultHeapIDDis 12, @PROCESSENTRY32.th32ModuleIDDis 16, @PROCESSENTRY32.cntThreadsDis 20,
                                   @PROCESSENTRY32.th32ParentProcessIDDis 24, @PROCESSENTRY32.pcPriClassBaseDis 28, @PROCESSENTRY32.dwFlagsDis 32,
                                   @PROCESSENTRY32.szExeFileDis 36

    ; Take a snapshot of all processes in the system.
    call 'kernel32.CreateToolhelp32Snapshot' &TH32CS_SNAPPROCESS, 0
    If eax = &INVALID_HANDLE_VALUE
        call ReportWinError {'CreateToolhelp32Snapshot: Invalid function on the system or it is corrupted !' 0}
        xor eax eax | ExitP
    End_If
    mov D@hSnapShot eax

    ; Set the size of the structure before using it.
    call ZeroMemory D@PROCESSENTRY32, Size_Of_PROCESSENTRY32
    mov D@PROCESSENTRY32.dwSizeDis Size_Of_PROCESSENTRY32

    ; Retrieve information about the first process,
    ; and exit if unsuccessful
    call 'kernel32.Process32First' D@hSnapShot, D@PROCESSENTRY32
    If eax = &FALSE
        call ReportWinError {'Process32First' 0} ; show cause of failure
        call 'KERNEL32.CloseHandle' D@hSnapShot ; clean the snapshot object
        xor eax eax | ExitP
    End_If


Converted:include \masm32\include\masm32rt.inc
.686
.xmm

.code
TITLE CODE
;________________________________________________________________________
IDD_MAINDIALOG=1000
IDC_OPEN=10
IDC_CLOSE=1
IDC_EXIT=2
IDC_TEXT=100
.data
hInstance dd 0
CommandLine dd 0
.code
Main:
invoke GetModuleHandleA, NULL
mov DWORD ptr [hInstance], eax
invoke GetCommandLineA
mov DWORD ptr [CommandLine], eax
invoke DialogBoxParamA, DWORD ptr [hinstance,], IDD_MAINDIALOG, NULL, ScanHeaderFile, NULL
invoke ExitProcess, eax
;_____________________________________________________________________________________________________________
; Tag Dialog 1000
.data
hEdit dd 0
.code
ScanHeaderFile proc @Adressee, @Message, @wParam, @lParam
pushad
.If @Message== WM_COMMAND ; User action
.If @wParam== IDC_EXIT ;, D@wParam = M03_Exit  ; User clicks on upper right [X] or Exited through the menu
invoke HeaderScanCleanUp, @Adressee
invoke EndDialog, @Adressee, NULL
.Else_If @wParam== IDC_CLOSE
invoke HeaderScanCleanUp, @Adressee
.End_If
.Else_If @Message== WM_INITDIALOG
;move D$hwnd D@Adressee
invoke SendMessageA, @Adressee, WM_SETTEXT, 0, chr$("Processes view", 0))
invoke GetDlgItem, @Adressee, IDC_TEXT
mov DWORD ptr [hEdit], eax
invoke SendMessageA, DWORD ptr [hEdit,], EM_SETLIMITTEXT, 0, 0 ; extends the text limit ot the edit control to 0-1
invoke GetProcessList
.Else_If @Message== WM_CLOSE
invoke HeaderScanCleanUp, @Adressee
invoke EndDialog, @Adressee, NULL
.Else
popad
mov eax, FALSE
ExitP
.End_If
L9: popad
mov eax, TRUE
ret
ScanHeaderFile endp
;___________________________________________________________________________________
HeaderScanCleanUp proc @Adressee
invoke SendDlgItemMessageA, @Adressee, IDC_TEXT, WM_SETTEXT, 0, NULL
ret
HeaderScanCleanUp endp
TITLE BeginProcess
;_________________________________________________________________________________________________
PROCESSENTRY32.dwSizeDis=0
PROCESSENTRY32.cntUsageDis 4
PROCESSENTRY32.th32ProcessIDDis 8
PROCESSENTRY32.th32DefaultHeapIDDis 12
PROCESSENTRY32.th32ModuleIDDis 16
PROCESSENTRY32.cntThreadsDis 20
PROCESSENTRY32.th32ParentProcessIDDis 24
PROCESSENTRY32.pcPriClassBaseDis 28
PROCESSENTRY32.dwFlagsDis 32
PROCESSENTRY32.szExeFileDis 36]
Size_Of_PROCESSENTRY32=296
GetProcessList proc
Local @hSnapShot, @dwPriorityClass, @hProcess
Local @hSnapShot, @dwPriorityClass, @hProcess
@PROCESSENTRY32.th32DefaultHeapIDDis 12, @PROCESSENTRY32.th32ModuleIDDis 16, @PROCESSENTRY32.cntThreadsDis 20,
@PROCESSENTRY32.th32ParentProcessIDDis 24, @PROCESSENTRY32.pcPriClassBaseDis 28, @PROCESSENTRY32.dwFlagsDis 32,
@PROCESSENTRY32.szExeFileDis 36
; Take a snapshot of all processes in the system.
invoke CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS, 0
.If eax== INVALID_HANDLE_VALUE
invoke ReportWinError,
xor eax, eax
ExitP
.End_If


You'll still get error messages, but they can more easily be corrected by hand.
Title: Re: RosAsm2Masm
Post by: guga on July 08, 2014, 06:24:31 AM
Excellent work JJ  :t :t :t