Assembly Language Programming

April 7, 2012

FASM – Win32 Dialog Boxes

Filed under: Assembly Language — Tags: , , — programmer209 @ 3:38 pm

FASM – How To Implement A Win32 Dialog Box

FASM – the Flat Assembler – is an assembler for the x86 assembly language. It is easy to install and use, you just download the zip file from the website and extract the folders to the location of your choice. It can even be run from a flash drive. Of course, to work with dialog boxes you will need to download the version of FASM that is targeted to the Windows O/S.

When the IDE is first executed it creates an INI file. The only thing to check when starting out with FASM is that this INI points to the correct location for the include files. Once this is done you can begin coding straight away. The FASM website is at:

http://flatassembler.net/

Related Posts

FASM – Win32 Property Sheets Example

FASM – Win32 Hello World

The Dialog Box

The dialog box I want to implement is from a previous project that I wrote in MS Visual C++. These extracts from the Visual Studio resource.h and RC files for that project specify the dialog box:

#define IDD_BIG_HEX_CALC_DIALOG         102
#define IDR_MAINFRAME                   128
#define IDC_PARAM_1                     1000
#define IDC_PARAM_2                     1001
#define IDC_PARAM_3                     1002
#define IDC_FUNCTION_LIST               1003
#define IDC_OUTPUT                      1004
#define IDC_BTN_CALL                    1005
#define IDC_BTN_RESET                   1006
#define IDC_CHECK1                      1007
#define IDC_DECIMAL_INPUT               1007
// Dialog

IDD_BIG_HEX_CALC_DIALOG DIALOGEX 0, 0, 360, 396
STYLE DS_SETFONT | DS_MODALFRAME | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "Big Hex Calculator"
FONT 11, "Lucida Console", 400, 0, 0x0
BEGIN
    EDITTEXT        IDC_PARAM_1,13,18,335,60,ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL
    EDITTEXT        IDC_PARAM_2,13,83,335,60,ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL
    EDITTEXT        IDC_PARAM_3,13,148,335,60,ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL
    CONTROL         "Inputs are decimal numbers",IDC_DECIMAL_INPUT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,212,120,10
    COMBOBOX        IDC_FUNCTION_LIST,13,249,170,149,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
    PUSHBUTTON      "Call Function",IDC_BTN_CALL,186,248,80,14
    PUSHBUTTON      "Clear Data",IDC_BTN_RESET,267,248,80,14
    EDITTEXT        IDC_OUTPUT,13,291,335,90,ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL
    GROUPBOX        "Enter Input Parameters",IDC_STATIC,7,5,346,224
    GROUPBOX        "Select Function",IDC_STATIC,7,235,346,35
    GROUPBOX        "Output",IDC_STATIC,7,277,346,112
END

The definitions in the extracts above need to be translated into the format for resources that is recognised by FASM. The #define directives from resource.h simply become FASM constant declarations at the top of the assembly source code file ( IDC_PARAM_1 = 1000 for example), while the layout of the dialog box as defined in the Visual Studio RC file is specified in the resource section within the ASM file. Note that FASM requires that the WS_VISIBLE attribute be explicitly defined for a control (or it won’t be visible). Also in FASM, text edit controls require the WS_BORDER attribute if you want them to have a border.

This dialog is intended to be the main window and user interface for some x86 code I have written to implement the modular exponentiation calculation (which will be in the next post). Therefore I have deleted some elements from the dialog that are not needed for this new project. These are highlighted in red.

The ASM Code

I basically adapted and cleaned up a couple of the examples I found on the FASM website to create this code, which can be used as a template and starting point for any FASM dialog box based program. The first line of the code tells FASM to output the executable in PE (portable executable) format. The second line specifies the entry point for the program (the start: label a few lines down). The rest of the code is divided up into a code section, an import data section, a data section and a resources section. Refer to section 2.4.2 of the PDF manual that comes with the FASM download for a full explanation of the directives used to define the structure of the code below.

The import data section is where the windows libraries, DLLs and functions needed for the program to work are specified. See section 3.1.2 in the PDF manual for more information.

To actually create the dialog box, all you do is call the DialogBoxParam function. This function needs the ID of the dialog resource ( IDD_BIG_HEX_CALC_DIALOG in this case ), and a pointer to the dialog box procedure. The dialog procedure is the user created callback function that processes the messages sent to the dialog box, which in this case is the function called DialogProc. All this function does in this example is change the message that is displayed in the text edit controls when the user presses a button. The null terminated strings for this are defined in the data section (which is named .text).

Imported windows functions such as DialogBoxParam are called using the invoke macro. See section 3.1.3 in the manual.

; -------------------------------------------------------------------------------------

 format PE GUI 4.0

 entry start

 include 'win32a.inc'

; -------------------------------------------------------------------------------------

 IDD_BIG_HEX_CALC_DIALOG = 102
 IDC_PARAM_1 = 1000
 IDC_PARAM_2 = 1001
 IDC_PARAM_3 = 1002
 IDC_OUTPUT = 1004
 IDC_BTN_CALL = 1005
 IDC_BTN_RESET = 1006

; -------------------------------------------------------------------------------------

 section '.code' code readable executable

  start:

    invoke GetModuleHandle,0
    invoke DialogBoxParam,eax,IDD_BIG_HEX_CALC_DIALOG,0,DialogProc,0

  exit:

    invoke  ExitProcess,0 

; -------------------------------------------------------------------------------------

proc DialogProc uses esi edi ebx,hwnddlg,msg,wparam,lparam

  cmp [msg],WM_INITDIALOG
  je .wminitdialog

  cmp [msg],WM_COMMAND
  je .wmcommand

  cmp [msg],WM_CLOSE
  je .wmclose

  xor eax,eax
  jmp .quit

  .wminitdialog:

    invoke SetDlgItemText,[hwnddlg],IDC_PARAM_1,szInitText
    invoke SetDlgItemText,[hwnddlg],IDC_PARAM_2,szInitText
    invoke SetDlgItemText,[hwnddlg],IDC_PARAM_3,szInitText
    invoke SetDlgItemText,[hwnddlg],IDC_OUTPUT,szInitText

    jmp .done

  .wmcommand:

    cmp [wparam], BN_CLICKED shl 16 + IDC_BTN_CALL
    je .COMPUTE

    cmp  [wparam], BN_CLICKED shl 16 + IDC_BTN_RESET
    je .CLEARDATA

    jmp .done

  .COMPUTE:

    invoke SetDlgItemText,[hwnddlg],IDC_PARAM_1,szComputeText
    invoke SetDlgItemText,[hwnddlg],IDC_PARAM_2,szComputeText
    invoke SetDlgItemText,[hwnddlg],IDC_PARAM_3,szComputeText
    invoke SetDlgItemText,[hwnddlg],IDC_OUTPUT,szComputeText

    jmp .done

  .CLEARDATA:

    invoke SetDlgItemText,[hwnddlg],IDC_PARAM_1,szClearText
    invoke SetDlgItemText,[hwnddlg],IDC_PARAM_2,szClearText
    invoke SetDlgItemText,[hwnddlg],IDC_PARAM_3,szClearText
    invoke SetDlgItemText,[hwnddlg],IDC_OUTPUT,szClearText

    jmp .done

  .wmclose:

    invoke EndDialog,[hwnddlg],0

  .done:

    mov eax,1

  .quit:

  ret       

endp

; -------------------------------------------------------------------------------------

section '.idata' import data readable writeable

  library kernel,'KERNEL32.DLL',\
          user,'USER32.DLL'

  import kernel,\
         GetModuleHandle,'GetModuleHandleA',\
         ExitProcess,'ExitProcess'

  import user,\
         DialogBoxParam,'DialogBoxParamA',\ 
         SetDlgItemText,'SetDlgItemTextA',\
         EndDialog,'EndDialog'

; -------------------------------------------------------------------------------------

section '.text' readable writeable

  szInitText db "Text set by WM_INITDIALOG.",0
  szComputeText db "The [Compute] button was pressed.",0
  szClearText db "The [Clear Data] button was pressed.",0

; -------------------------------------------------------------------------------------

section '.rc' resource data readable

  directory RT_DIALOG,dialogs

  resource dialogs,IDD_BIG_HEX_CALC_DIALOG,LANG_ENGLISH+SUBLANG_DEFAULT,mod_exp_dialog

  dialog mod_exp_dialog,\
  'FASM - Dialog Example',0,0,360,396,\
  DS_MODALFRAME+WS_MINIMIZEBOX+WS_POPUP+WS_VISIBLE+WS_CAPTION+WS_SYSMENU,\
  0,0,"Lucida Console",11

  dialogitem 'BUTTON','Enter Input Parameters',-1,7,5,346,224,BS_GROUPBOX+WS_VISIBLE,0
  dialogitem 'BUTTON',"Output",-1,7,277,346,112,BS_GROUPBOX+WS_VISIBLE,0

  dialogitem 'EDIT',0,IDC_PARAM_1,13,18,335,60,ES_MULTILINE+ES_AUTOVSCROLL+ES_WANTRETURN+WS_VSCROLL+WS_BORDER+WS_VISIBLE,0
  dialogitem 'EDIT',0,IDC_PARAM_2,13,83,335,60,ES_MULTILINE+ES_AUTOVSCROLL+ES_WANTRETURN+WS_VSCROLL+WS_BORDER+WS_VISIBLE,0
  dialogitem 'EDIT',0,IDC_PARAM_3,13,148,335,60,ES_MULTILINE+ES_AUTOVSCROLL+ES_WANTRETURN+WS_VSCROLL+WS_BORDER+WS_VISIBLE,0

  dialogitem 'BUTTON',"Compute",IDC_BTN_CALL,186,248,80,14,BS_PUSHBUTTON+WS_VISIBLE,0
  dialogitem 'BUTTON',"Clear Data",IDC_BTN_RESET,267,248,80,14,BS_PUSHBUTTON+WS_VISIBLE,0

  dialogitem 'EDIT',0,IDC_OUTPUT,13,291,335,90,ES_MULTILINE+ES_AUTOVSCROLL+ES_WANTRETURN+WS_VSCROLL+WS_BORDER+WS_VISIBLE,0

  enddialog

; -------------------------------------------------------------------------------------
Advertisements

Create a free website or blog at WordPress.com.

%d bloggers like this: