News:

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

Need help with double for loop

Started by bigantiman, May 01, 2005, 09:07:21 PM

Previous topic - Next topic

bigantiman

Hi 2 all.
i'm trying to convert a petzold C program on page 650 bitblt.c into a assembly vedsion, but i'm having trouble with the double loop.
the codes works, but i'm not getting the desired effect (Figure 14-2 ).
Can someone provide me with a example of the loop and give the code a glimps for newbie errors.
i kinda messed it up.


.586
.model flat,stdcall
option casemap:none

   include windows.inc
   include user32.inc
   include kernel32.inc
   include gdi32.inc
   include pnglib.inc
   
   include c:\masm32\macros\macros.asm
   includelib gdi32.lib
   includelib user32.lib
   includelib kernel32.lib
   includelib pnglib.lib

wndWdth equ 800
wndHgth equ 600
IDB_BUTTON equ 102

WinMain proto :DWORD,:DWORD,:DWORD,:DWORD

.data
ClassName db "BitBltClass32",0
AppName  db "BitBlt Conversion 2 Win32Asm",0
exitText db "CREDITS ",13,10
db "-------------------------------------------------------",13,10
db "PNG lib (C)opyright 2005 Thomas Bleeker (www.madwizard.com)",0

cxSource dd 0
cySource dd 0
cyClient dd 0
cxClient dd 0
x dd 0
y dd 0
.data?
hInstance dd ?
CommandLine LPSTR ?
hButton dd ?
hdcClient dd ?
hdcWindow dd ?




.code


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


start:

invoke GetModuleHandle, NULL
mov    hInstance,eax

invoke GetCommandLine
mov    CommandLine,eax

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

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
LOCAL wc:WNDCLASSEX
LOCAL msg:MSG
LOCAL hWnd:HWND

mov   wc.cbSize,SIZEOF WNDCLASSEX
mov   wc.style, CS_HREDRAW or CS_VREDRAW
mov   wc.lpfnWndProc, OFFSET WndProc
mov   wc.cbClsExtra,NULL
mov   wc.cbWndExtra,NULL
push  hInstance
pop   wc.hInstance
mov   wc.hbrBackground,COLOR_BTNFACE+1
mov   wc.lpszMenuName,NULL
mov   wc.lpszClassName,OFFSET ClassName

invoke LoadIcon,NULL,IDI_INFORMATION
mov   wc.hIcon,eax
mov   wc.hIconSm,eax

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

invoke RegisterClassEx, addr wc
INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
        WS_OVERLAPPEDWINDOW and (not ( WS_SIZEBOX or WS_MAXIMIZEBOX)),CW_USEDEFAULT,\
        CW_USEDEFAULT,wndWdth,wndHgth,NULL,NULL,\
        hInst,NULL
mov   hWnd,eax
push eax
call CenterScreen
invoke ShowWindow, hWnd,SW_SHOWNORMAL
invoke UpdateWindow, hWnd

@@MESS_LOOP:
invoke GetMessage, ADDR msg,NULL,0,0
test eax,eax
jz @@MESS_END
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
jmp @@MESS_LOOP
@@MESS_END:
mov     eax,msg.wParam
ret
WinMain endp
WndProc proc hWnd:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
LOCAL ps:PAINTSTRUCT
LOCAL rect:RECT

.IF [uMsg]==WM_CREATE


invoke CreateWindowEx,0,\
SADD("BUTTON"),\
SADD("&Exit"),\
WS_CHILD or WS_VISIBLE or BS_PUSHBUTTON,\
706,\
522,\
68,31,hWnd,IDB_BUTTON,hInstance,0
mov hButton,eax
invoke GetSystemMetrics,SM_CXSIZEFRAME
push eax ;save it into edx
pop edx
invoke GetSystemMetrics,SM_CXSIZE
mov eax,edx ; SM_CXSIZEFRAME+SM_CXSIZE
push eax
pop cxSource ; and store it into the var


invoke GetSystemMetrics,SM_CYSIZEFRAME
push eax ;save it into edx
pop edx
invoke GetSystemMetrics,SM_CYCAPTION
mov eax,edx ; SM_CYSIZEFRAME+SM_CYCAPTION
push eax
pop cySource ; and store it into the var

.ELSEIF [uMsg]==WM_SIZE


xor eax,eax
movzx eax,word ptr [lParam] ;LOWORD lParam

push eax
pop cxClient

xor eax,eax
movzx eax,word ptr [lParam+2] ;HIWORD lParam

push eax
pop cyClient


.ELSEIF [uMsg]==WM_PAINT
invoke BeginPaint,hWnd,ADDR ps
mov hdcClient,eax
invoke GetWindowDC,hWnd
mov hdcWindow,eax


xor edx,edx
xor ecx,ecx
mov x,0
mov y,0

; for ( y = 0 ; y < cyClient, y += cySource )
; for ( x = 0 ; x < cyCleint, x += cxSource )
; {
; BitBlt(hdcClient,etc etc etc )
; }

mov edx, y
mov ecx, x
.while (ecx < [cxClient] )&& (edx < [cyClient] )
invoke BitBlt,hdcClient,x,y,cxSource,cySource,hdcWindow,0,0,SRCCOPY
.break .if ecx == cxClient
add ecx,cxSource
add edx,cySource
.endw

invoke EndPaint,hWnd,ADDR ps



.ELSEIF [uMsg]==WM_COMMAND
.IF word ptr [wParam+2] == BN_CLICKED

invoke MessageBoxEx, hWnd,\
SADD("You Pressed the  Exit Button Baby"),\
SADD("Message"),\
MB_OK,NULL
invoke AnimateWindow, hWnd,900,AW_HIDE or AW_BLEND
invoke PostQuitMessage,NULL

.ENDIF

.ELSEIF [uMsg]==WM_CLOSE
invoke MessageBoxEx, hWnd, SADD("CEE U LATER "),SADD("Message"),MB_YESNO,0
.IF eax ==IDYES
invoke AnimateWindow, hWnd,900,AW_HIDE or AW_BLEND
invoke DestroyWindow,  hWnd
.ENDIF

.ELSEIF [uMsg]==WM_DESTROY
invoke PostQuitMessage,0
xor eax,eax
ret

.ELSE
invoke DefWindowProc,hWnd,uMsg,wParam,lParam
ret
.ENDIF

xor eax,eax
ret

WndProc endp




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



CenterScreen proc hWnd:HWND
; Centerscreen by Izcelion
LOCAL DlgHeight:DWORD
LOCAL DlgWidth:DWORD
LOCAL DlgRect:RECT
LOCAL DesktopRect:RECT
     
     invoke GetWindowRect,hWnd,ADDR DlgRect
     invoke GetDesktopWindow
     mov ecx,eax
     invoke GetWindowRect,ecx,addr DesktopRect
     push 0
     mov eax,DlgRect.bottom
     sub eax,DlgRect.top
     mov DlgHeight,eax
     push eax
     mov eax,DlgRect.right
     sub eax,DlgRect.left
     mov DlgWidth,eax
     push eax
     mov eax,DesktopRect.bottom
     sub eax,DlgHeight
     shr eax,1
     push eax
     mov eax,DesktopRect.right
     sub eax,DlgWidth
     shr eax,1
     push eax
     push hWnd
     call MoveWindow
     ret
CenterScreen endp

end start






roticv


; for ( y = 0 ; y < cyClient, y += cySource )
; for ( x = 0 ; x < cyCleint, x += cxSource )
; {
; BitBlt(hdcClient,etc etc etc )
; }


should be something like

  xor ecx, ecx ;x
  xor edx, edx ;y
  jmp start_
mainloop:
  add edx,cySource
start_:
  jmp start2
loop2:
  add ecx, cxSource
start2:
  invoke BitBlt ....
  cmp ecx, cyCleint
  jl loop2
  cmp edx, cyCleint
  jl mainloop


Untested piece of coe

tenkey


for ( y = 0 ; y < cyClient; y += cySource )
    for ( x = 0 ; x < cxClient; x += cxSource )
    {
        BitBlt(hdcClient,etc etc etc )
    }


The double for-loop can be rewritten in C as


y = 0;
while (y < cyClient)
{
    x = 0;
    while (x < cxClient)
    {
        BitBlt(hdcClient,etc etc etc );

        x += cxSource;
    }

    y += cySource;
}

A programming language is low level when its programs require attention to the irrelevant.
Alan Perlis, Epigram #8

bigantiman

Quote from: roticv on May 02, 2005, 03:20:07 AM

; for ( y = 0 ; y < cyClient, y += cySource )
; for ( x = 0 ; x < cyCleint, x += cxSource )
; {
; BitBlt(hdcClient,etc etc etc )
; }


should be something like

  xor ecx, ecx ;x
  xor edx, edx ;y
  jmp start_
mainloop:
  add edx,cySource
start_:
  jmp start2
loop2:
  add ecx, cxSource
start2:
  invoke BitBlt ....
  cmp ecx, cyCleint
  jl loop2
  cmp edx, cyCleint
  jl mainloop


Untested piece of coe
Thanks rotivc and tenkey, for the examples.
The loop works, aldo i did not get the effect that i wanted to get ( as in the book ), got to check my coded to see where the error is.
But thanks anyway.