News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Linked Lists BasePntr's display

Started by Tight_Coder_Ex, May 23, 2011, 12:46:59 PM

Previous topic - Next topic

Tight_Coder_Ex

Bench.exe is an application for testing functionality of my linked list project.  This version displays node numbers for each BasePntr.


                .586P
                .model flat, stdcall
                 option casemap:none

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

        includelib      kernel32.lib
        includelib      user32.lib
        includelib      gdi32.lib
        includelib      Horizons.lib

        include         LStructs.inc

        ScanMap         proto

                extern  ListParams:DWORD

                public  BMap

        ArraySize       equ     sizeof LL_PARAM.BasePntr / 2
        DisplaySize     equ     24

                .const
;  *--*  *--*  *--*  *--*  *--*  *--*  *--*  *--*  *--*  *--*  *--*  *--*  *--*  *--*  *--*  *--*  *--*

                dd      0, (BMapEnd - BMap) /8
  BMap          dd      WM_PAINT, PaintWnd
  BMapEnd       equ     $

  DispFmt       db      '%4X'                      ; Hexidecimal value associated with field

                .data
; <--->  <--->  <--->  <--->  <--->  <--->  <--->  <--->  <--->  <--->  <--->  <--->  <--->  <--->  <--->

  DispPntr      db      '<   ='                         ; Index indicator

                .data?
;  [***]  [***]  [***]  [***]  [***]  [***]  [***]  [***]  [***]  [***]  [***]  [***]  [***]  [***]  [***]

  LineSpc       dd      ?
  Top           dd      ?
  Margin        dd      ?
   
                .code
;==========================================================================================================
;  Metrics for WM_PAINT are calculated so text will be centered vertically, and DispPntr & DispFmt are
;  right aligned.

;       ENTRY:  EAX = Handle to this window
;               ESI = lParam (CREATESTRUCT) as passed to WM_CREATE

;  NOTE: As this window hasn't been hooked yet, its entry point for WM_CREATE is still in the windows
;        procedure applicaiton defined class "DISP".
;----------------------------------------------------------------------------------------------------------

CBCreate    proc

        LOCAL   TxtM : TEXTMETRIC

                add     esi, 16                         ; Bump to "cy" in CREATESTRUCT
                push    eax                             ;  1 : hWnd
                call    GetDC                           ; USER32

        ; Don't need to load effective address of TxtM as ESP is already pointing there

                push    esp                             ;  2 : lptm
                push    eax                             ;  1 : hdc
                call    GetTextMetrics                  ; GDI32

                pop     eax                             ; tmHeight is the only value we need
                mov     LineSpc, eax                    ; Is needed in WM_PAINT
                mov     edx, eax
                shr     edx, 2

                imul    eax, ArraySize                  ; Number of lines to be displayed
                mov     ecx, eax                        ; Move out of way
                lodsd                                   ; Get physical height of window.
                sub     eax, ecx
                shr     eax, 1                          ; (Height - DisplayArea) / 2
                sub     eax, edx
                mov     Top, eax                        ; Also needed in WM_PAINT

        ; Now that vertical position has been calculated, the right margin for DispFmt & DispPntr need
        ; be calculated.  Nothing scientific here as I skewed some of the values by guessing what they
        ; should be by observation.

                lodsd                                   ; "cx" from CREATESTRUCT                               
                mov     ecx, eax                        ; Save copy of total width                       
                shr     eax, 1                          ; Determine center margin
                sub     eax, 14                         ; Skew DispPntr to left
                mov     edi, offset Margin
                stosw                                   ; Margins is actually small RECT
                sub     ecx, 30                         ; DispFmt's right margin
                mov     eax, ecx
                stosw

                stc                                     ; Inhibit default processing
                ret

CBCreate    endp

;==========================================================================================================
;----------------------------------------------------------------------------------------------------------

PaintWnd       proc    private uses ebx

        LOCAL   Ps : PAINTSTRUCT, Rc : RECT, NextLine : DWORD         

                lea     eax, Ps                         ; Get pointer to local variable
                push    eax                             ;  2 : LPPAINTSTRUCT
                push    dword ptr [esi]                 ;  1 : hwnd
                call    BeginPaint                      ; User32 API
                sub     esp, 8                          ; Setup for EndPaint API in epilogue

        .if     !eax                                    ; Was DC returned in EAX
                int     3                       ; Will develop error routine if necessary

      .else

        ASSUME  ebx : PTR LL_PARAM

                mov     esi, offset ListParams \
                                    + LL_PARAM.BasePntr ; Pointer to BasePntr in LL_PARAM
                xor     ecx, ecx
                mov      cl, ArraySize                  ; ECX = Number of WORDS in array
                mov     edi, offset DispPntr            ; Pointer to array of node values
                mov     eax, Top                        ; As calculated in CBCreate
                mov     NextLine, eax                   ; Save local copy so Top won't be altered
                sub     esp, DisplaySize                ; Make a bit of room for wsprintf

        @@:     push    ecx                             ; Loop counter will be destroyed by API's

        ; Setup AL & CL for ShowLine

                xor     eax, eax
                mov     ecx, eax
                mov      al, 5                          ; DispPntr's length less NULL
                mov      cl, byte ptr Margin            ; Right margin for TextOut
                call    ShowLine                        ; Display line

        ; Now we need to get value from array

                push    edi                             ; Save pointer to DisPntr string
                lea     edi, [esp+8]                    ; Point to local display area
                xor     eax, eax
                lodsw                                   ; Get next value from BasePntr

        ; Setup for formatting text @ EDI

                push    eax                             ;  3 : Arg1  Node # 0 - FFFF
                push    offset DispFmt                  ;  2 : lpFmt
                push    edi                             ;  1 : lpOut
                call    wsprintf                        ; USER32

                add     esp, 12                         ; Waste API's arguments
                mov     ecx, eax                        ; This is so we know bits 31 - 04 are NULL
                mov      cl, byte ptr Margin + 2        ; DispFmt's right margin
                call    ShowLine                        ; and display

                mov     eax, LineSpc                    ; Get skew to next line
                add     eax, dword ptr NextLine
                mov     NextLine, eax                   ; Save next position

                pop     edi                             ; Restore pointer to DispPntr
                pop     ecx                             ; and interation counter

        ; Based on interation counter we can determine which letter is being displayed

                mov     eax, ecx
                sub     eax, 29
                not     eax
                or       al, 40H
                inc      al

        ; I would have liked to figure out a better way of doing this, but this is only a benchmarking
        ; application

        .if      al > 'Z'
                mov      al, '>'
     .endif

                mov     [edi], al                       ; Save next letter to be displayed @ DisPntr
                loop    @B                              ; Until ECX is exhausted

        ASSUME  ebx : NOTHING

                add     esp, DisplaySize                ; Waste wsprintf's display area

     .endif                             ; BeginPaint returned null
                call    EndPaint
                stc                                     ; Inhibit default prodcessing
                ret

        option  epilogue : none

        ; Local subroutine and this method makes it show up with PaintWnd in graph display of IDA.

  ShowLine:     push    eax                             ;  5 : cbString
                push    edi                             ;  4 : lpString
                push    NextLine                        ;  3 : nYStart
                push    ecx

                sub     esp, 8                          ; Space for 4th argument
                push    esp                             ;  4 : lpSize
                push    eax                             ;  3 : cbString
                push    edi                             ;  2 : lpString
                push    Ps.hdc                          ;  1 : hdc
                call    GetTextExtentPoint32            ; Gdi32 API
                pop     eax
                pop     edx
                pop     ecx

                sub     ecx, eax
                push    ecx                             ;  2 : nXStart
                push    Ps.hdc                          ;  1 : hdc
                call    TextOut
                ret

PaintWnd       endp

;==========================================================================================================
; Entry point for window that displays values with each associated BasePntr ( 0 - 28 )
;----------------------------------------------------------------------------------------------------------

BWndProc       proc

                mov     eax, offset BMap - 8            ; Point to hWnd, Msg, wParam, lParam
                jmp     ScanMap                         ; Parse map.

BWndProc       endp

                end