PowerBASIC Peer Support Forums
 

Go Back   PowerBASIC Peer Support Forums > User to user Discussions > PowerBASIC Inline Assembler

PowerBASIC Inline Assembler User to user discussions concerning use of Inline Assembler in PowerBASIC programs. Questions, answers, and sample code are all welcomed.

Reply
 
Thread Tools Display Modes
  #1  
Old Apr 17th, 2012, 12:18 AM
Steve Hutchesson Steve Hutchesson is offline
Member
 
Join Date: Oct 1999
Location: Sydney Australia
Posts: 2,363
Window with asm msgloop and WndProc.

Had a little time to waste, this is the result. It builds at 8704 bytes. There is no great gain in writing this style of code in PB but it can be done with the minimum of overhead using the FASTPROC notation.

Code:
' いいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい

    #include "\basic\include\win32api.inc"

    MACRO entry_point = PBmain as LONG
    MACRO WM_DESTROY  = 2
    MACRO WM_QUIT     = &H12

  ' -----------------------
  ' WndProc stack arguments
  ' -----------------------
    MACRO wpHandle    = DWORD PTR [ebp+8]
    MACRO wpMessage   = DWORD PTR [ebp+12]
    MACRO wpWparam    = DWORD PTR [ebp+16]
    MACRO wpLparam    = DWORD PTR [ebp+20]

    GLOBAL hInstance         as DWORD
    GLOBAL hIcon             as DWORD
    GLOBAL hWnd              as DWORD

    GLOBAL hUser             as DWORD
    GLOBAL hKernel           as DWORD
    GLOBAL pPostQuitMessage  as DWORD
    GLOBAL pDefWindowProc    as DWORD
    GLOBAL pTranslateMessage as DWORD
    GLOBAL pDispatchMessage  as DWORD
    GLOBAL pGetMessage       as DWORD

    GLOBAL pGetModuleHandle  as DWORD
    GLOBAL pLoadIcon         as DWORD
    GLOBAL pGetSystemMetrics as DWORD

    GLOBAL DisplayName       as STRINGZ * 32
    GLOBAL szClassName       as STRINGZ * 32

' いいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい

FUNCTION entry_point

    LOCAL Wid          as DWORD
    LOCAL Hgt          as DWORD
    LOCAL wcex         as WNDCLASSEX
    LOCAL Sw           as DWORD
    LOCAL Sh           as DWORD

    hUser   = LoadLibrary("user32.dll")
    hKernel = LoadLibrary("kernel32.dll")

    GetAddresses

    PREFIX "!"

    push 0
    call pGetModuleHandle
    mov hInstance, eax

    push 2
    push hInstance
    call pLoadIcon
    mov hIcon, eax

    push 0                    ' SM_CXSCREEN   ' screen width
    call pGetSystemMetrics
    mov Sw, eax

    push 1                    ' SM_CYSCREEN   ' screen height
    call pGetSystemMetrics
    mov Sh, eax

    END PREFIX

    szClassName = "PB_FASTPROC_Class"

  ' ----------------------------------------------------------------------
  ' set the arguments to determine the characteristics of the window class
  ' ----------------------------------------------------------------------
    wcex.cbSize        = SIZEOF(wcex)
    wcex.style         = %CS_BYTEALIGNCLIENT or %CS_BYTEALIGNWINDOW
    wcex.lpfnWndProc   = CODEPTR(WndProc)
    wcex.cbClsExtra    = 0
    wcex.cbWndExtra    = 0
    wcex.hInstance     = hInstance
    wcex.hIcon         = hIcon
    wcex.hCursor       = LoadCursor(%NULL,ByVal %IDC_ARROW)
    wcex.hbrBackground = %COLOR_BTNFACE + 1
    wcex.lpszMenuName  = %NULL
    wcex.lpszClassName = VarPtr(szClassName)
    wcex.hIconSm       = hIcon

  ' ---------------------------------------------
  ' register the class with those characteristics
  ' ---------------------------------------------
    RegisterClassEx wcex

  ' -----------------------------------------------
  ' Set Width & Height to percentage of screen size
  ' -----------------------------------------------
    Wid = Sw * .70
    Hgt = Sh * .70

  ' ---------------------------------------
  ' limit the aspect ratio for wide screens
  ' ---------------------------------------
    If Wid > Hgt * 1.4 Then
      Wid = Hgt * 1.4
    End If

    DisplayName = "PB FASTPROC Demo"

  ' ------------------------
  ' Window is self centering
  ' ------------------------
    hWnd = CreateWindowEx( _
           %WS_EX_LEFT, _                  ' extended style
           szClassName, _                  ' window class name
           DisplayName, _                  ' window title
           %WS_OVERLAPPEDWINDOW, _         ' window style
           Sw\2-(Wid\2), _                 ' initial x position
           Sh\2-(Hgt\2), _                 ' initial y position
           Wid, _                          ' initial x size
           Hgt, _                          ' initial y size
           %NULL, _                        ' parent window handle
           %NULL, _                        ' window menu handle
           hInstance, _                    ' program instance handle
           ByVal %NULL)                    ' creation parameters

   '-------------------------

    ShowWindow hWnd, %SW_SHOW
    UpdateWindow hWnd

    ! call MessageLoop

    FreeLibrary hUser
    FreeLibrary hKernel

    FUNCTION = 0

END FUNCTION

' いいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい

FASTPROC MessageLoop

    PREFIX "!"

    push ebp                                ; set up a stack frame
    mov ebp, esp
    sub esp, 96                             ; create LOCAL variable space

    push esi
    push edi

    xor edi, edi                            ; zero EDI

    lea esi, [ebp-96]                       ; load LOCAL stack space for the MSG structure in ESI
    jmp intoloop

  LoopStart:
    push esi
    call pTranslateMessage
    push esi
    call pDispatchMessage
  intoloop:
    push edi
    push edi
    push edi
    push esi
    call pGetMessage                        ; process messages until
    test eax, eax                           ; GetMessage returns zero
    jnz LoopStart

    pop edi
    pop esi

    leave                                   ; restore ESP & EBP
    ret

    END PREFIX

END FASTPROC

' いいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい

FASTPROC WndProc

    PREFIX "!"

    push ebp                                  ; set up a stack frame
    mov ebp, esp

    cmp wpMessage, WM_QUIT
    jne lbl0
    xor eax, eax
    jmp outa_here
  lbl0:

    cmp wpMessage, WM_DESTROY
    jne lbl1
    push 0
    call pPostQuitMessage
  lbl1:

    push wpLparam
    push wpWparam
    push wpMessage
    push wpHandle
    call pDefWindowProc

  outa_here:
    leave                                     ; exit the stack frame
    ret 16                                    ; balance stack on exit

    END PREFIX

END FASTPROC

' いいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい

SUB GetAddresses()

    pPostQuitMessage  = GetProcAddress(hUser,"PostQuitMessage")
    pDefWindowProc    = GetProcAddress(hUser,"DefWindowProcA")

    pTranslateMessage = GetProcAddress(hUser,"TranslateMessage")
    pDispatchMessage  = GetProcAddress(hUser,"DispatchMessageA")
    pGetMessage       = GetProcAddress(hUser,"GetMessageA")
    pLoadIcon         = GetProcAddress(hUser,"LoadIconA")
    pGetSystemMetrics = GetProcAddress(hUser,"GetSystemMetrics")

    pGetModuleHandle  = GetProcAddress(hKernel,"GetModuleHandleA")

END SUB

' いいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいいい
__________________
hutch at movsd dot com
www.masm32.com
Reply With Quote
  #2  
Old May 5th, 2012, 03:26 AM
frank bruebach frank bruebach is offline
Member
 
Join Date: Oct 2009
Location: germany
Posts: 223
WM_Paint solution is just missing ;)

many thanks steve for your nice win api example, that task I have trie to solve some month ago!

@steve:

can you help to fix my "WM_PAINT" problem? I have added some new commands and have only the problem to convert these four lines for "WM_PAINT" part to asm code.

Code:
                    
    #INCLUDE "windows.inc" '"\basic\include\win32api.inc"  
 

    MACRO entry_point = PBmain AS LONG  
    MACRO WM_DESTROY  = 2  
    MACRO WM_QUIT     = &H12  
    MACRO WM_PAINT    = 15 'franks part  
    MACRO WM_CLOSE    = 16 'franks part  
 

  ' -----------------------  
  ' WndProc stack arguments  
  ' -----------------------  
    MACRO wpHandle    = DWORD PTR [ebp+8]  
    MACRO wpMessage   = DWORD PTR [ebp+12]  
    MACRO wpWparam    = DWORD PTR [ebp+16]  
    MACRO wpLparam    = DWORD PTR [ebp+20]  
 

    GLOBAL hInstance         AS DWORD  
    GLOBAL hIcon             AS DWORD  
    GLOBAL hWnd              AS DWORD  
    GLOBAL cRect             AS rect  
    GLOBAL Paintst           AS paintstruct  
    GLOBAL hDC               AS LONG  
 

    GLOBAL hUser             AS DWORD  
    GLOBAL hKernel           AS DWORD  
    GLOBAL hGdi32            AS DWORD 'franks part  
    GLOBAL pPostQuitMessage  AS DWORD  
    GLOBAL pDefWindowProc    AS DWORD  
    GLOBAL pTranslateMessage AS DWORD  
    GLOBAL pDispatchMessage  AS DWORD  
    GLOBAL pGetMessage       AS DWORD  
 

    GLOBAL pGetModuleHandle  AS DWORD  
    GLOBAL pLoadIcon         AS DWORD  
    GLOBAL pGetSystemMetrics AS DWORD  
 

    GLOBAL pGetStockObject   AS DWORD  'franks part  
    GLOBAL pGetClientRect    AS DWORD  'franks part  
    GLOBAL pBeginPaint       AS DWORD  'franks part  
    GLOBAL pEndPaint         AS DWORD  'franks part  
    GLOBAL pDrawText         AS DWORD  'franks part  
 

    GLOBAL DisplayName       AS STRINGZ * 32  
    GLOBAL szClassName       AS STRINGZ * 32  
 

 '   
 

 FUNCTION entry_point  
 

    LOCAL Wid          AS DWORD  
    LOCAL Hgt          AS DWORD  
    LOCAL wcex         AS WNDCLASSEX  
    LOCAL Sw           AS DWORD  
    LOCAL Sh           AS DWORD  
 

    hUser   = LoadLibrary("user32.dll")  
    hKernel = LoadLibrary("kernel32.dll")  
    hGdi32 = LoadLibrary("gdi32.dll") 'franks part  
 

    GetAddresses  
 

    PREFIX "!"  
 

    push 0  
    call pGetModuleHandle  
    mov hInstance, eax  
 

    push 2  
    push hInstance  
    call pLoadIcon  
    mov hIcon, eax  
 

    push 0                    ' SM_CXSCREEN   ' screen width  
    call pGetSystemMetrics  
    mov Sw, eax  
 

    push 1                    ' SM_CYSCREEN   ' screen height  
    call pGetSystemMetrics  
    mov Sh, eax  
 

    END PREFIX  
 

    szClassName = "PB_FASTPROC_Class"  
 

  ' ----------------------------------------------------------------------  
  ' set the arguments to determine the characteristics of the window class  
  ' ----------------------------------------------------------------------  
    wcex.cbSize        = SIZEOF(wcex)  
    wcex.style         = %CS_BYTEALIGNCLIENT OR %CS_BYTEALIGNWINDOW  
    wcex.lpfnWndProc   = CODEPTR(WndProc)  
    wcex.cbClsExtra    = 0  
    wcex.cbWndExtra    = 0  
    wcex.hInstance     = hInstance  
    wcex.hIcon         = hIcon  
    wcex.hCursor       = LoadCursor(%NULL,BYVAL %IDC_ARROW)  
    wcex.hbrBackground = %COLOR_BTNFACE + 1 'pGetStockObject %WHITE_BRUSH  
    wcex.lpszMenuName  = %NULL  
    wcex.lpszClassName = VARPTR(szClassName)  
    wcex.hIconSm       = hIcon  
 

  ' ---------------------------------------------  
  ' register the class with those characteristics  
  ' ---------------------------------------------  
    RegisterClassEx wcex  
 

  ' -----------------------------------------------  
  ' Set Width & Height to percentage of screen size  
  ' -----------------------------------------------  
    Wid = Sw * .70  
    Hgt = Sh * .70  
 

  ' ---------------------------------------  
  ' limit the aspect ratio for wide screens  
  ' ---------------------------------------  
    IF Wid > Hgt * 1.4 THEN  
      Wid = Hgt * 1.4  
    END IF  
 

    DisplayName = "PB FASTPROC Demo"  
 

  ' ------------------------  
  ' Window is self centering  
  ' ------------------------  
    hWnd = CreateWindowEx( _  
           %WS_EX_LEFT, _                  ' extended style  
           szClassName, _                  ' window class name  
           DisplayName, _                  ' window title  
           %WS_OVERLAPPEDWINDOW, _         ' window style  
           Sw\2-(Wid\2), _                 ' initial x position  
           Sh\2-(Hgt\2), _                 ' initial y position  
           Wid, _                          ' initial x size  
           Hgt, _                          ' initial y size  
           %NULL, _                        ' parent window handle  
           %NULL, _                        ' window menu handle  
           hInstance, _                    ' program instance handle  
           BYVAL %NULL)                    ' creation parameters  
 

   '-------------------------  
 

    ShowWindow hWnd, %SW_SHOW  
    UpdateWindow hWnd  
 

    ! call MessageLoop  
 

    FreeLibrary hUser  
    FreeLibrary hKernel  
 

    FUNCTION = 0  
 

 END FUNCTION  
 

 '   
 

 FASTPROC MessageLoop  
 

    PREFIX "!"  
 

    push ebp                                ; set up a stack frame  
    mov ebp, esp  
    sub esp, 96                             ; create LOCAL variable space  
 

    push esi  
    push edi  
 

    xor edi, edi                            ; zero EDI  
 

    lea esi, [ebp-96]                       ; load LOCAL stack space for the MSG structure in ESI  
    jmp intoloop  
 

  LoopStart:  
    push esi  
    call pTranslateMessage  
    push esi  
    call pDispatchMessage  
  intoloop:  
    push edi  
    push edi  
    push edi  
    push esi  
    call pGetMessage                        ; process messages until  
    test eax, eax                           ; GetMessage returns zero  
    jnz LoopStart  
 

    pop edi  
    pop esi  
 

    leave                                   ; restore ESP & EBP  
    ret  
 

    END PREFIX  
 

 END FASTPROC  
 

 '   
 

 FASTPROC WndProc  
 

    PREFIX "!"  
 

    push ebp                                  ; set up a stack frame  
    mov ebp, esp  
 

    cmp wpMessage, WM_PAINT  
    ; pGetClientRect  hWnd,cRect  
    ; hDC=pBeginPaint hWnd,Paintst  
    ; DrawText hDC,"Hello World!",-1,cRect,0x25  
    ; call pBeginPaint  
    ; call pEndPaint  
 

    cmp wpMessage, WM_QUIT  
    jne lbl0  
    xor eax, eax  
    jmp outa_here  
  lbl0:  
 

    cmp wpMessage, WM_DESTROY  
    jne lbl1  
    push 0  
    call pPostQuitMessage  
  lbl1:  
 

    push wpLparam  
    push wpWparam  
    push wpMessage  
    push wpHandle  
    call pDefWindowProc  
 

  outa_here:  
    leave                                     ; exit the stack frame  
    ret 16                                    ; balance stack on exit  
 

    END PREFIX  
 

      '------------  
      'case %WM_PAINT  
      '============  
      'GetClientRect  hWnd,cRect  
      'hDC=BeginPaint hWnd,Paintst  
 

      'SetBkColor   hdc,yellow  
      'SetTextColor hdc,red  
      'DrawText hDC,"Hello World!",-1,cRect,0x25  
      'EndPaint hWnd,Paintst  
 

 END FASTPROC  
 

 '   
 

 SUB GetAddresses()  
 

    pPostQuitMessage  = GetProcAddress(hUser,"PostQuitMessage")  
    pDefWindowProc    = GetProcAddress(hUser,"DefWindowProcA")  
 

    pTranslateMessage = GetProcAddress(hUser,"TranslateMessage")  
    pDispatchMessage  = GetProcAddress(hUser,"DispatchMessageA")  
    pGetMessage       = GetProcAddress(hUser,"GetMessageA")  
    pLoadIcon         = GetProcAddress(hUser,"LoadIconA")  
    pGetSystemMetrics = GetProcAddress(hUser,"GetSystemMetrics")  
 

    pGetStockObject   = GetProcAddress(hGdi32,"GetStockObject") 'franks part  
    pBeginPaint       = GetProcAddress(hUser,"BeginPaint") 'franks part  
    pEndPaint         = GetProcAddress(hUser,"EndPaint")   'franks part  
    pGetClientRect    = GetProcAddress(hUser,"GetClientRect") 'franks part  
    pDrawText         = GetProcAddress(hUser,"DrawTextA")  'franks part  
 

    pGetModuleHandle  = GetProcAddress(hKernel,"GetModuleHandleA")  
 END SUB  
 

 '  
further problem zones:
getstockobjects %WHITE_BRUSH (doesn't work, I don't know why) for background modus

best regards, thanks again for you really interesting solution, I think I couldn't convert that all to asm code, nice week-end, frank

Last edited by frank bruebach; May 5th, 2012 at 03:29 AM.
Reply With Quote
  #3  
Old May 9th, 2012, 07:32 PM
Michael Mattias Michael Mattias is offline
Member
 
Join Date: Aug 1998
Location: Racine WI USA
Posts: 35,685
Quote:
getstockobject[] %WHITE_BRUSH (doesn't work, I don't know why) for background modus
Sure it does, it works here. I use it all the time.

Note correct syntax is
Code:
   WCEX.hBrBackGround =  GetStockObject (%WHITE_BRUSH)   ' parens
I don't even know that it should compile when you use
Code:
   WCEX.hBrBackGround = GetStockObject %WHITE_BRUSH   ' no parens
And unless "GetStockObjects" (with an S) is some kind of symbol defined in your program this should not compile, unless #DIM ALL is off and the %WHITE_BRUSH is ignored (Should not be ignored as this cannot be valid syntax).

"Actual allegedly failing code not shown"

OR...
You are pre-empting the use of the default class brush in WM_ERASEBKGND and/or overwriting it in WM_PAINT.


OOPS... that appears to be the part of the code you haven't written yet. Maybe that's why it "don't work."

MCM
Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 08:48 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Copyright 1999-2011 PowerBASIC, Inc. All Rights Reserved.
Error in my_thread_global_end(): 1 threads didn't exit