Author Topic: Window based application from NASM command line Interface ?  (Read 454 times)

Offline sunshine33

  • Jr. Member
  • *
  • Posts: 21
Window based application from NASM command line Interface ?
« on: April 14, 2018, 04:15:05 PM »
Is it possible to use this same code in NASM , i think this was originally written for MASM .

Code: [Select]
; #########################################################################

.386
.model flat, stdcall
option casemap :none   

; #########################################################################

include windows.inc
include user32.inc
include kernel32.inc

includelib user32.lib
includelib kernel32.lib

; #########################################################################

szText macro name, text:vararg
local lbl
jmp lbl
name db text, 0
lbl:
endm

WinMain proto :dword, :dword, :dword, :dword
WndProc proto :dword, :dword, :dword, :dword

; #########################################################################

.data

hInstance dd ?
lpszCmdLine dd ?

; #########################################################################

.code

start:

invoke GetModuleHandle, NULL
mov hInstance, eax

invoke GetCommandLine
mov lpszCmdLine, eax

invoke WinMain, hInstance, NULL, lpszCmdLine, SW_SHOWDEFAULT
invoke ExitProcess, eax


; ------------------------------------------------------------------------
; WinMain
;
; Main program execution entry point
; ------------------------------------------------------------------------
WinMain proc hInst :dword,
hPrevInst :dword,
szCmdLine :dword,
nShowCmd :dword

local wc :WNDCLASSEX
local msg :MSG
local hWnd :HWND

szText szClassName, "BasicWindow"
szText szWindowTitle, "First Window"

mov wc.cbSize, sizeof WNDCLASSEX
mov wc.style, CS_HREDRAW or CS_VREDRAW or CS_BYTEALIGNWINDOW
mov wc.lpfnWndProc, WndProc
mov wc.cbClsExtra, NULL
mov wc.cbWndExtra, NULL

push hInst
pop wc.hInstance

mov wc.hbrBackground, COLOR_BTNFACE + 1
mov wc.lpszMenuName, NULL
mov wc.lpszClassName, offset szClassName

invoke LoadIcon, hInst, IDI_APPLICATION
mov wc.hIcon, eax
mov wc.hIconSm, eax

invoke LoadCursor, hInst, IDC_ARROW
mov wc.hCursor, eax

invoke RegisterClassEx, addr wc

invoke CreateWindowEx, WS_EX_APPWINDOW, addr szClassName, addr szWindowTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, hInst, NULL

mov hWnd, eax

invoke ShowWindow, hWnd, nShowCmd
invoke UpdateWindow, hWnd

MessagePump:

invoke GetMessage, addr msg, NULL, 0, 0

cmp eax, 0
je MessagePumpEnd

invoke TranslateMessage, addr msg
invoke DispatchMessage, addr msg

jmp MessagePump

MessagePumpEnd:

mov eax, msg.wParam
ret

WinMain endp


; ------------------------------------------------------------------------
; WndProc
;
; Handles all of the messages sent to the window
; ------------------------------------------------------------------------
WndProc proc hWin :dword,
uMsg :dword,
wParam :dword,
lParam :dword

.if uMsg == WM_DESTROY

invoke PostQuitMessage, 0

xor eax, eax
ret

.endif

invoke DefWindowProc, hWin, uMsg, wParam, lParam

ret

WndProc endp

end start

Offline avcaballero

  • Full Member
  • **
  • Posts: 126
  • Country: es
    • Abre los Ojos al Ensamblador
Re: Window based application from NASM command line Interface ?
« Reply #1 on: April 14, 2018, 07:00:18 PM »
No, you have to translate it to the Nasm sintax, since each compiler has its own one. You may use the NasmX package for it, for example, that has some handy examples for that, not only for Windows, also for Linux, etc. Here is an example of a simple Windows with NasmX:
Code: [Select]

%include '..\..\windemos.inc'

cdXPos      EQU  128
cdYPos      EQU  128
cdXSize     EQU  320
cdYSize     EQU  200
cdColFondo  EQU  COLOR_BTNFACE + 1
cdVIcono    EQU  IDI_APPLICATION
cdVCursor   EQU  IDC_ARROW
cdVBarTipo  EQU  NULL
cdVBtnTipo  EQU  WS_VISIBLE+WS_OVERLAPPEDWINDOW

entry Entrada

[section .text]

  proc   WndProc, ptrdiff_t hwnd, dword msg, size_t wparam, size_t lparam
      locals none
      cmp      dword [argv(.msg)], WM_DESTROY
      je       .wmdestroy
      .wmdefault:
          invoke   DefWindowProc, ptrdiff_t [argv(.hwnd)], dword [argv(.msg)], size_t [argv(.wparam)], size_t [argv(.lparam)]
          jmp      .finish
      .wmdestroy:
          invoke    DestroyWindow, ptrdiff_t [argv(.hwnd)]
          invoke   PostQuitMessage, NULL
      .finish:
  endproc

  proc   WinMain, ptrdiff_t hinst, ptrdiff_t hpinst, ptrdiff_t cmdln, dword dwshow
  locals none

      ; invoke GetStockObject, LTGRAY_BRUSH
      ; mov    ptrdiff_t [wc + WNDCLASSEX.hbrBackground], __AX
      invoke LoadIcon, NULL, IDI_APPLICATION
      mov    __DX, __AX
      mov    __AX, ptrdiff_t [argv(.hinst)]
      mov    __BX, ptrdiff_t NombreClase
      mov    __CX, ptrdiff_t WndProc
      mov    ptrdiff_t [wc + WNDCLASSEX.hInstance], __AX
      mov    ptrdiff_t [wc + WNDCLASSEX.lpszClassName], __BX
      mov    ptrdiff_t [wc + WNDCLASSEX.lpfnWndProc], __CX
      mov    ptrdiff_t [wc + WNDCLASSEX.hIcon], __DX
      mov    ptrdiff_t [wc + WNDCLASSEX.hIconSm], __DX
      invoke LoadCursorA, NULL, IDC_ARROW
      mov    dword [wc + WNDCLASSEX.hCursor], eax
      invoke RegisterClassEx, wc

      invoke CreateWindowEx, cdVBarTipo, NombreClase, MsgCabecera, \
                  cdVBtnTipo,\
                  cdXPos, cdYPos, cdXSize, cdYSize, NULL, NULL, \
                  ptrdiff_t [wc + WNDCLASSEX.hInstance], NULL
      mov    size_t[hWnd], __AX
      invoke ShowWindow, [hWnd], dword[argv(.dwshow)]
      invoke UpdateWindow, [hWnd]

  .msgloop:
      invoke GetMessage, message, NULL, NULL, NULL
      cmp    eax, dword 0
      je     .exit
      invoke TranslateMessage, message
      invoke DispatchMessage, message
      jmp    .msgloop

  .exit:

      mov __AX, size_t[message + MSG.wParam]

  endproc

  proc    Entrada, ptrdiff_t argcount, ptrdiff_t cmdline
      locals none
      invoke GetModuleHandle, NULL
      mov    ptrdiff_t [hInstance], __AX
      invoke WinMain, hInstance, NULL, NULL, SW_SHOWNORMAL
      invoke ExitProcess, __AX
  endproc


[section .bss]
  hInstance:   reserve(ptrdiff_t) 1
  hWnd:        reserve(ptrdiff_t) 1

[section .data]
    MsgCabecera: declare(NASMX_TCHAR) NASMX_TEXT("Hola mundo en ventana Windows"), 0x0
    NombreClase: declare(NASMX_TCHAR) NASMX_TEXT("SimpleWinClass"), 0x0
    MsgError:    declare(NASMX_TCHAR) NASMX_TEXT("Carga inicial fallida."),0x0

    NASMX_ISTRUC wc, WNDCLASSEX
        NASMX_AT cbSize,        sizeof(WNDCLASSEX)
        NASMX_AT style,         CS_VREDRAW + CS_HREDRAW
        NASMX_AT lpfnWndProc,   NULL
        NASMX_AT cbClsExtra,    NULL
        NASMX_AT cbWndExtra,    NULL
        NASMX_AT hInstance,     NULL
        NASMX_AT hIcon,         NULL
        NASMX_AT hCursor,       NULL
        NASMX_AT hbrBackground, COLOR_BTNFACE + 1
        NASMX_AT lpszMenuName,  NULL
        NASMX_AT lpszClassName, NULL
        NASMX_AT hIconSm,       NULL
    NASMX_IENDSTRUC

    NASMX_ISTRUC message, MSG
        NASMX_AT hwnd,     NULL
        NASMX_AT message,  NULL
        NASMX_AT wParam,   NULL
        NASMX_AT lParam,   NULL
        NASMX_AT time,     NULL
        NASMX_ISTRUC pt, POINT
            NASMX_AT x,       NULL
            NASMX_AT y,       NULL
        NASMX_IENDSTRUC
    NASMX_IENDSTRUC
PS. NasmX is a package of includes,  libs, macros prepared to use with Nasm. There are people that prefer to use raw Nasm compiler without those packages.
« Last Edit: April 14, 2018, 07:02:36 PM by avcaballero »

Offline sunshine33

  • Jr. Member
  • *
  • Posts: 21
Re: Window based application from NASM command line Interface ?
« Reply #2 on: April 15, 2018, 04:50:43 AM »
You mean each Assembler has its own way of including the windows OS files ?

That is where the difference is ?

Offline avcaballero

  • Full Member
  • **
  • Posts: 126
  • Country: es
    • Abre los Ojos al Ensamblador
Re: Window based application from NASM command line Interface ?
« Reply #3 on: April 15, 2018, 09:04:07 AM »
Not only that. In fact most assemblers are very similar if you go to the raw code, in what they differ is mainly the way they try to make the assembler code in a higher level. Rosasm, for example, has a terrible sintax different with anything else I have met.

  - There is no "invoke" machine instruction. It is a macro that let's you use in an only line:
Code: [Select]
invoke myproc, param1, param2, ..., paramn    is translated in a stdcall way as:
Code: [Select]
push paramn
...
push param2
push param1
call myproc

  - There is no "procedure" machine instruction. It is a macro that makes the usual work for you:
Code: [Select]
proc WndProc, param1, param2, param3
  local locvble
endproc
it does
Code: [Select]
WndProc:
  push ebp
  mov  ebp, esp
  ; locvble = esp-4
  pop  ebp
ret 3*4   ; 3 params

Etc. Macros and preprocessor are totally different in all of them.

Masm uses the variables in the next way (they all work the same):
Code: [Select]
mov eax, dword ptr [vble]
mov eax, [vble]      ; the compiler understands that it is "dword ptr" because of eax
mov eax, vble

Nevertheless Nasm would use the next (notice that there's noo "ptr"):
Code: [Select]
mov eax, dword [vble]
mov eax, [vble]      ; the compiler understands that it is "dword" because of eax

To get the vble direction masm does
Code: [Select]
mov eax, offset vblewhile nasm does (notice the absence of offset, and it may confuse you with the access of its value compared with masm):
Code: [Select]
mov eax, vble
« Last Edit: April 15, 2018, 09:11:56 AM by avcaballero »

Offline sunshine33

  • Jr. Member
  • *
  • Posts: 21
Re: Window based application from NASM command line Interface ?
« Reply #4 on: April 16, 2018, 04:25:15 AM »
Sorry for the late reply ,
Thanks a lot for the explanation .

After comparing the syntax of both the NASM Assembler and MASM Assembler , i have decided to stay with MASM Assembler instead .
MASM Assembler syntax looks a bit more user friendly .