How to compile this code in Assembly on Windows?

Asked

Viewed 2,375 times

4

I was seeing a creation of a basic window on Assembly that displays a message, already installed the compiler NASM but error to compile.

.386
.MODEL FLAT, STDCALL

INCLUDE windows.inc
INCLUDE kernel32.inc
INCLUDE user32.inc
INCLUDELIB kernel32.lib
INCLUDELIB user32.lib

.DATA
    WndClsName BYTE "AsmWnd", 0h;
    WndTitleName BYTE "Hello, World!", 0h;
    MsgBoxTxt BYTE "Programadores de verdade programam assim", 0h;
    CmdShow DWORD SW_SHOWDEFAULT;

.DATA?
    window WNDCLASSEX {};
    hInstance HINSTANCE ?;
    hWnd HWND ?;
    message MSG {};

.CODE
Entry:
    push 0h;
    call GetModuleHandle;
    mov hInstance, eax;

    mov window.cbSize, SIZEOF WNDCLASSEX;
    mov window.hbrBackground, COLOR_WINDOW;
    mov window.hIcon, 0h;
    mov window.hIconSm, 0h;
    mov window.cbClsExtra, 0h;
    push IDC_HAND;
    push 0h;
    call LoadCursor;
    mov window.hCursor, eax;
    push hInstance;
    pop window.hInstance;
    mov window.lpszMenuName, 0h;
    mov window.lpszClassName, OFFSET WndClsName;
    mov window.style, CS_VREDRAW or CS_HREDRAW;
    mov window.lpfnWndProc, OFFSET WndProc;

    push eax;
    lea eax, window;
    push eax;
    call RegisterClassEx;
    pop eax;

    push 0h;
    push hInstance;
    push 0h;
    push 0h;
    push 250d;
    push 250d;
    push 250d;
    push 250d;
    push WS_OVERLAPPEDWINDOW;
    lea eax, WndTitleName;
    push eax;
    lea eax, WndClsName;
    push eax;
    push WS_EX_TOPMOST;
    call CreateWindowExA;
    mov hWnd, eax;
    cmp hWnd, 0h;
    jne _Ok;
    push 1h; 
    call ExitProcess;
    _Ok:
    push CmdShow;
    push hWnd;
    call ShowWindow;
    push hWnd;
    call UpdateWindow;

    _GetMessageLoop:
    push 0h;
    push 0h;
    push 0h;
    lea eax, message;
    push eax;
    call GetMessage;
    cmp eax, 0h;
    je _EndMessageLoop;
    lea eax, message;
    push eax;
    call TranslateMessage;
    lea eax, message;
    push eax;
    call DispatchMessage;
    jmp _GetMessageLoop;

    _EndMessageLoop:

    mov eax, message.wParam

WndProc proc hWindow:HWND, uMsg:UINT, wParam:DWORD, lParam:DWORD

    cmp uMsg, WM_DESTROY;
    je _WM_DESTROY;
    cmp uMsg, WM_LBUTTONDOWN;
    je _WM_LBUTTONDOWN;

    push lParam;
    push wParam;
    push uMsg;
    push hWindow;
    call DefWindowProc;
    jmp _EndWndProc;

    _WM_LBUTTONDOWN:
    push MB_OK or MB_ICONINFORMATION;
    push OFFSET WndTitleName;
    push OFFSET MsgBoxTxt;
    push hWindow;
    call MessageBoxA;
    jmp _EndWndProc;

    _WM_DESTROY:
    push 0h;
    call PostQuitMessage;

    _EndWndProc:

    Ret
WndProc EndP

END Entry;
  • It seems to be the syntax of MASM. Post the error messages.

  • And how to compile?

  • If it is MASM, with the MASM compiler.

  • So it is in Masm.

1 answer

3


To compile this code, you must use the compiler of MASM, nay NASM, sane assemblers distinguished.

For your code to execute, make the following changes:

  1. Below the directive .model, use the directive option casemap, option casemap can be ALL, NONE or NOTPUBLIC, is the last one to default. Using option casemap:none, the MASM preserves the identifiers box. Using option casemap:all, the MASM passes all identifiers to uppercase, for example, both msgboxtxt how much MsgBoxTxt are transformed into MSGBOXTXT). The goal is to use NONE so that the box of identifiers are preserved, then below the directive .model do:

    .386
    .MODEL FLAT, STDCALL
    option casemap:none
    
  2. To avoid the error fatal error A1000: cannot open file, put the full path of the files .inc and .lib. Change:

    INCLUDE windows.inc
    INCLUDE kernel32.inc
    INCLUDE user32.inc
    
    INCLUDELIB kernel32.lib
    INCLUDELIB user32.lib
    

    For:

    include \masm32\include\windows.inc
    include \masm32\include\kernel32.inc
    include \masm32\include\user32.inc
    
    includelib \masm32\lib\kernel32.lib
    includelib \masm32\lib\user32.lib
    
  3. Save the file Ctrl+S, and in the top menu click on ProjectBuild All, then run the program by clicking on Run Program.

    Upshot:

    inserir a descrição da imagem aqui

Code can be reduced using INVOKE to call a function, instead of placing the function arguments on the stack and calling the function with CALL.

.386
.model flat, stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib

.DATA
    WndClsName BYTE "AsmWnd", 0h;
    WndTitleName BYTE "Hello, World!", 0h;
    MsgBoxTxt BYTE "Programadores de verdade programam assim", 0h;
    CmdShow DWORD SW_SHOWDEFAULT;

.DATA?
    window WNDCLASSEX {};
    hInstance HINSTANCE ?;
    hWnd HWND ?;
    message MSG {};

.CODE
Entry:
    invoke GetModuleHandle, 0h;
    mov hInstance, eax;
    mov window.cbSize, SIZEOF WNDCLASSEX;
    mov window.hbrBackground, COLOR_WINDOW;
    mov window.hIcon, 0h;
    mov window.hIconSm, 0h;
    mov window.cbClsExtra, 0h;
    invoke LoadCursor, 0h, IDC_HAND;

    mov window.hCursor, eax;
    push hInstance;
    pop window.hInstance;
    mov window.lpszMenuName, 0h;
    mov window.lpszClassName, offset WndClsName;
    mov window.style, CS_VREDRAW or CS_HREDRAW;
    mov window.lpfnWndProc, offset WndProc;

    invoke RegisterClassEx, offset window;
    invoke CreateWindowExA, WS_EX_TOPMOST, offset WndClsName, offset WndTitleName, WS_OVERLAPPEDWINDOW, 250d, 250d, 250d, 250d, 0h, 0h, hInstance, 0h;
    mov hWnd, eax;
    cmp hWnd, 0h;
    jne _Ok;
    invoke ExitProcess, 1h;

    _Ok:
    invoke ShowWindow, hWnd, CmdShow;
    invoke UpdateWindow, hWnd;

    _GetMessageLoop:
    invoke GetMessage, offset message, 0h, 0h, 0h;
    cmp eax, 0h;
    je _EndMessageLoop;
    invoke TranslateMessage, offset message;
    invoke DispatchMessage, offset message;
    jmp _GetMessageLoop;

    _EndMessageLoop:
    mov eax, message.wParam

WndProc proc hWindow:HWND, uMsg:UINT, wParam:DWORD, lParam:DWORD
    cmp uMsg, WM_DESTROY;
    je _WM_DESTROY;
    cmp uMsg, WM_LBUTTONDOWN;
    je _WM_LBUTTONDOWN;

    invoke DefWindowProc, hWindow, uMsg, wParam, lParam;
    jmp _EndWndProc;

    _WM_LBUTTONDOWN:
    invoke MessageBoxA, hWindow, offset MsgBoxTxt, offset WndTitleName, MB_OK or MB_ICONINFORMATION
    jmp _EndWndProc;

    _WM_DESTROY:
    invoke PostQuitMessage, 0h;

    _EndWndProc:

    Ret
WndProc EndP
end Entry;
  • 1

    Thanks, it helped a lot.

  • @Leonardo Dispo. Welcome to Sopt. =)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.