Hi all!
I don?t like API functions corrupting registers (of course, except of eax and eip). So I have just written a macro that preserves all registers before calling a function and then restores them.



run macro func: VARARG
local i
i = 0
for arg, <func>
i = i + 1
exitm
endm
if i eq 0
.err <run macro cannot be called without parameters>
else
sub esp, 4
pushad
invoke func
mov dword ptr [esp+32], eax
popad
mov eax, dword ptr [esp]
add esp, 4
endif
endm


So you can write:
run MessageBox, NULL, addr szMessage, addr szCaption, MB_OK

The cost of this macro is 15 extra bytes added into your program. What can you say about it? ;)
Posted on 2002-05-31 05:30:06 by vkim
vkim,

your macro works, but why not coding:



run macro func: VARARG
local i
i = 0
for arg, <func>
i = i + 1
exitm
endm
if i eq 0
.err <run macro cannot be called without parameters>
else
pushad
invoke func
mov dword ptr [esp+28], eax
popad
endif
endm


since the position of EAX in the PUSHAD "struct" is documented?
Posted on 2002-05-31 05:55:53 by japheth
vkim, if i=0 then func will be blank:
run macro func: VARARG

ifb <&func>
.err <run macro cannot be called without parameters>
else
pushad
invoke func
mov dword ptr [esp+28], eax
popad
endif
endm
Posted on 2002-05-31 06:04:53 by bitRAKE
Oh, thank you, bitRAKE and japheth!!! The code became so small!
Posted on 2002-05-31 06:32:10 by vkim
While on the subject of preserving registers, how expensive are push/popad. Would we be better off using them instead of "uses edi esi ebx"?
Posted on 2002-05-31 10:17:47 by Eóin
It is a slowdown garbage...
If you know how to write pure assembly code
you don't need to preserve registers when callng API ....
Posted on 2002-05-31 14:02:07 by buliaNaza
buliaNaza, these are for debug macros - speed is of little concern as the code will not be present in released code. Sometimes I wish the APIs were C calling convention so we could really optimize calling them. :)
Posted on 2002-05-31 15:12:25 by bitRAKE
Hello buliaNaza ,

Can you post an small example with some comments please.
Posted on 2002-05-31 15:29:03 by cmax
:) :) Hi, cmax
Of course, I can post an example but the question is WHY?
I mean the way of thinking here...plz take a look:

Q: "does anyone have a clue how to find the exact address of the PE-Header of an EXE-File.
My problem is, that the size of the DOS-Stub isn't defined exactly."
...............
...............

A1: I use

;Start:
;invoke GetModuleHandle, 0 ; slow
;mov hInstance, eax
;........
;........
;End Start

Start:
mov esi, offset Start ; faster
and esi, 0FFFF0000h
.....
.....

A2:
.DATA
hInstance dd offset Start
.CODE

Start:
and hInstance, 0FFFF0000h


Reply:
"What's the problem with GetModuleHandle(NULL) ? You call it once,
at program startup... what's the use of these funky methods apart
from looking smart?"

Or

A:
pxor mm7,mm7
@@: movq mm0,
pminub mm0,
pminub mm0,
pminub mm0,
pminub mm0,
pminub mm0,
pminub mm0,
pminub mm0,
pcmpeqb mm0,mm7
add eax,64
pmovmskb ecx,mm0
jecxz @B

Replay:
"... and doesn't work on older machines like the Pentium, Pentium MMX, Pentium Pro, Pentium 2
(does it work on the P3 ? ), K6/K6-2 (does the Athlon support these instructions ?) and so on.
I think it's a nice idea, but the use is currently not that high, since some (or the most ?) people still use these
"old" processors, which does not support these instructions. "

Or

"This is my first post here, and I'm wondering why you use MMX and other weird instructions to write these routines.
They are basic routines which don't need tremendous optimisation.
Personally, if I had to put the code into a real program, I'll put tower's code to avoid crash on weird systems."
...............
...............
Or
...............
..............
..............
will become too long.........

So, I agree with The_Svin:

"It is sign of corrage that you submit the code.
When you don't have already examples of how to deal some algo,
it's 99 % chance that you do code that slower then somewere existing. Most of so to called gurus didn't create any ideas - they just pick them from others.
So coward in the case would pretend that he knows something but don't have time to show it."



:(
Posted on 2002-05-31 16:09:49 by buliaNaza
WHYyyyy ? has spoken :)

The fact is i was the biggest Dump A** out here and i am just getting hip to the true heavy ways of this game. And i don't ever want to dream again... i want to make sure no mather what.

PS: I got few more miles to travel but when i get there they will have to say D*MMMME, WHERE DID HE COME FROM.

Thanks a Million buliaNaza

Posted on 2002-05-31 16:33:36 by cmax
buliaNaza, hope the variety of coders here doesn't discourage you. Of course, everyone has an opinion. :) Don't forget that not everybody programs in asm for speed/size optimization. It is obvious that you work to create some optimal code, and you have a good understanding of the instruction set and basic programming structures. Unfortunately, that is not the case for everyone here. I have studied the Intel manuals, MASM documentation, and much other material -- it take some time to learn ASM. Not everyone has that time. I try to have much respect for people - where ever they may be in their life or in their programming -- it is not aways an easy thing. ;)
Posted on 2002-05-31 16:51:10 by bitRAKE
cmax,
ok...ok.. Just copy and paste code and
link with -> /SUBSYSTEM:WINDOWS /RELEASE
/MERGE:.rdata=.text /SECTION:.text" , "CEWR" test.obj



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

include c:\masm32\include\windows.inc
include c:\masm32\include\gdi32.inc
include c:\masm32\include\user32.inc
include c:\masm32\include\kernel32.inc

includelib c:\masm32\lib\gdi32.lib
includelib c:\masm32\lib\user32.lib
includelib c:\masm32\lib\kernel32.lib

.code ;

Start: ;
jmp Start1 ;
hWnd dd 0
dStack dd 0 ;
cObjects dd 17
lphObjects dd 17 Dup(0)
LL1 dd 6 Dup(0) ; number of dll +1
LLoffset dd offset LL1 ;
szTest db "I don't want to feel guilty if my programs"
db " don't start with :",13,10
db " Start:",13,10
db " invoke GetModuleHandle,NULL",10,13
db " mov hInstance, eax",10,13
db " invoke WinMain,eax,0,0,0",10,13
db " invoke ExitProcess,eax",10,13
db " END Start",0
;....................... API .................................................. ;
aLoadLibrary DD 64616F4Ch
aGlobalUnlock DD 7262694Ch
aGlobalLock DD 41797261h
aGetModuleHandle DD 6F6C4700h
aFreeLibrary DD 556C6162h
aExitProcess DD 636F6C6Eh
aSetBkColor DD 6C47006Bh
aSelectObject DD 6C61626Fh
aGetDeviceCaps DD 6B636F4Ch
aDeleteObject DD 74654700h
aCreateFontIndirect DD 75646F4Dh
aTranslateMessage DD 6148656Ch
aShowWindow DD 656C646Eh
aSetWindowLong DD 72460041h
aSetForegroundWindow DD 694C6565h
aSetFocus DD 72617262h
aSendMessage DD 78450079h
aReleaseDC DD 72507469h
aRegisterClassEx DD 7365636Fh
aPostQuitMessage DD 00000073h
aOpenClipboard DD 44470000h
aLoadIcon DD 2E323349h
aLoadCursor DD 006C6C64h
aIsClipboardFormatAvailable DD 42746553h
aGetSystemMetrics DD 6C6F436Bh
aGetSysColor DD 5300726Fh
aGetMessage DD 63656C65h
aGetDC DD 6A624F74h
aGetClipboardData DD 00746365h
aFindWindow DD 44746547h
aEndPaint DD 63697665h
aDrawText DD 70614365h
aDispatchMessage DD 65440073h
aDestroyWindow DD 6574656Ch
aDefWindowProc DD 656A624Fh
aCreateWindowEx DD 43007463h
aCloseClipboard DD 74616572h
aCallWindowProc DD 6E6F4665h
aBeginPaint DD 646E4974h
DD 63657269h
DD 00004174h
DD 55000000h
DD 33524553h
DD 6C642E32h
DD 7254006Ch
DD 6C736E61h
DD 4D657461h
DD 61737365h
DD 53006567h
DD 57776F68h
DD 6F646E69h
DD 65530077h
;My Internal Buffer_Start Here
DD 6E695774h
DD 4C776F64h
DD 41676E6Fh
DD 74655300h
DD 65726F46h
DD 756F7267h
DD 6957646Eh
DD 776F646Eh
DD 74655300h
DD 75636F46h
DD 65530073h
DD 654D646Eh
DD 67617373h
DD 52004165h
DD 61656C65h
DD 43446573h
DD 67655200h
DD 65747369h
DD 616C4372h
DD 78457373h
DD 6F500041h
DD 75517473h
DD 654D7469h
DD 67617373h
DD 704F0065h
DD 6C436E65h
DD 6F627069h
DD 00647261h
DD 64616F4Ch
DD 6E6F6349h
DD 6F4C0041h
DD 75436461h
DD 726F7372h
DD 73490041h
DD 70696C43h
DD 72616F62h
DD 726F4664h
DD 4174616Dh
DD 6C696176h
DD 656C6261h
DD 74654700h
DD 74737953h
DD 654D6D65h
DD 63697274h
DD 65470073h
DD 73795374h
DD 6F6C6F43h
DD 65470072h
DD 73654D74h
DD 65676173h
DD 65470041h
DD 00434474h
DD 43746547h
DD 6270696Ch
DD 6472616Fh
DD 61746144h
DD 6E694600h
DD 6E695764h
DD 41776F64h
DD 646E4500h
DD 6E696150h
DD 72440074h
DD 65547761h
DD 00417478h
DD 70736944h
DD 68637461h
DD 7373654Dh
DD 41656761h
DD 73654400h
DD 796F7274h
DD 646E6957h
DD 4400776Fh
DD 69576665h
DD 776F646Eh
DD 636F7250h
DD 72430041h
DD 65746165h
DD 646E6957h
DD 7845776Fh
DD 6C430041h
DD 4365736Fh
DD 6270696Ch
DD 6472616Fh
DD 6C614300h
DD 6E69576Ch
DD 50776F64h
DD 41636F72h
DD 67654200h
DD 61506E69h
DD 00746E69h
DD 00000000h
DD 00000000h
;................................................................................. ;
ClassName db "test_class", 0
ProgName db "bnTest",0
MainW dd 642
MainH dd 442 wccbSize dd sizeof WNDCLASSEX
wcstyle dd CS_HREDRAW or CS_VREDRAW
wclpfnWndProc dd offset WndProc
wccbClsExtra dd 0
wccbWndExtra dd 0
wchInstance dd 0
wchIcon dd 0
wchCursor dd 0
wchbrBackground dd COLOR_APPWORKSPACE+1
wclpszMenuName dd 0
wclpszClassName dd offset ClassName
wchIconSm dd 0
OnCreate: ;
mov ecx, [esp+(1+0)*4] ; hWnd
mov hWnd, ecx ;
jmp DefWindowProc ;
;................................................................................. ;
Start1: ;
;Get Kernel32 module base address ;
mov edi, offset aLoadLibrary ;
mov ebx, [esp] ; Return address of call to CreateProcess
mov ecx, 0FFFFF800h ;
mov [esp-(1+0)*4], edi ; edi-> offset aLoadLibrary
and ebx, 0FFFF1000h ; the last three are zeros
sub esp,(1+0)*4 ; simulate push edi
KrnlLoop: ;Get Kernel32 module base address
mov edx, [ebx-1000h+3Ch] ; Take beginning of PE header
sub ebx, 1000h ; Scan backward
test edx, ecx ; Is it a PE header?
jnz KrnlLoop ; No, search again
cmp ebx, [ebx+edx+34h] ; compare current address with the
; addr that PE should be loaded at
jnz KrnlLoop ; if different search again
;My GetProcAddress by Name ;
FindAPI: ; GetProcAddress
mov [esp-(4+0)*4], edi ; edi-> pNameAPI
mov [esp-(6+0)*4], ebx ; ebx-> current dll base address
mov eax, [ebx+edx+120] ; eax-> RVA of Export Table
xor edx, edx ; edx=nMin
mov ebp, [ebx+eax+32] ; ebp-> Address Name Table
mov [esp-(8+0)*4], eax ; eax->RVA of Export Table
add ebp, ebx ; ebp-> Addr Name Table Offset
mov eax, [ebx+eax+24] ; eax = num of API Names-> nMax
To_Min: ; Find Index
mov esi, eax ; esi-> new nMax
add eax, edx ; edx-> nMin ;eax->new current index
NewSrch: ;
shr eax, 1 ; eax-> current index / 2
mov ebx, [esp-(6+0)*4] ; ebx-> current dll base address
mov edi, [esp-(4+0)*4] ; edi-> pNameAPI
add ebx, [eax*4+ebp] ; ebp-> Addr Name Table Offset
;Compare strings ;
test edi, 3 ; edi-> pNameAPI
jz Aligned ;
test edi, 1 ;
jz Not_Aligned ;
movzx ecx, byte ptr [edi] ; edi-> pNameAPI
inc edi ;
cmp cl, [ebx] ; ebx-> API Names Table
jnz Not_equal ;
;test cl, cl ; No API with 1 character
;jz Found ;
inc ebx ;
test edi, 2 ;
jz Aligned ;
Not_Aligned: ;
movzx ecx, word ptr [edi] ;
add edi, 2 ;
cmp cl, [ebx] ;
jnz Not_equal ;
;test cl, cl ; No API with 2 characters
;jz Found_1 ;
cmp ch, [ebx+1] ;
lea ebx, [ebx+2] ;
jnz Not_equal ;
;test ch, ch ; No API with 3 characters
;jz Found_2 ;
Aligned: ;
mov ecx, [edi] ;
add ebx, 4 ;
cmp cl, [ebx-4] ;
jnz Not_equal ;
test cl, cl ;
jz Found_1 ;
cmp ch, [ebx-3] ;
jnz Not_equal ;
test ch, ch ;
jz Found_2 ;
shr ecx,16 ;
add edi, 4 ;
cmp cl, [ebx-2] ;
jnz Not_equal ;
test cl, cl ;
jz Found_3 ;
cmp ch, [ebx-1] ;
jz Found_4 ;
Not_equal: ; move the index (eax) to nMin or to nMax
dec eax ; eax-> new current index = eax-1
jc To_Min ;
lea edx, [eax+2] ; edx-> new nMax = eax+1
lea eax, [eax+esi+2] ; edx-> nMin ebx-> nMax
jmp NewSrch ; eax-> new current index
Found_3: ;
dec edi ;
jmp Found ;
Found_2: ;
inc edi ;
Found_1: ;
inc edi ;
jmp Found ;
Found_4: ;
test ch, ch ;
jnz Aligned ;
Found: ; API Index is in eax
mov ebx, [esp-(6+0)*4] ; ebx-> current dll base address
mov esi, [esp-(8+0)*4] ; esi-> RVA of Export Table
mov edx, [esi+ebx+36] ; edx->RVA of Ordinal Table
lea ecx, [ebx+eax*2] ; index-> eax*2 for word table
mov [esp-(10+0)*4], eax ; save eax-> current index
movzx eax,word ptr [ecx+edx] ; ecx = Ordinal number
mov ecx, [esi+ebx+28] ; eax-> RVA of Address table
lea eax, [ecx+eax*4] ; ecx = ordinal #
mov edx, ebx ;
add edx, [eax+ebx] ; eax-> RVA of API
mov eax, [esp-(0+0)*4] ; current offset for API address
mov ecx, [edi] ; last API ?
mov [eax], edx ; save API address
add eax, 4 ; room for next API address
mov [esp-(0+0)*4], eax ; save it
jecxz NextDll ;
mov eax, [esp-(10+0)*4] ; eax-> current index
xor edx, edx ; edx=nMin=0
mov [esp-(8+0)*4], esi ; esi-> RVA of Export Table
mov esi, eax ; esi-> nMax = eax-> current index
mov [esp-(4+0)*4], edi ;
jmp NewSrch ; next API
NextDll: ;
mov ecx, [edi+4] ; last DLL ?
add edi, 4 ; Next DLL
jecxz EndGetProc ; Exit
push edi ;
call aGetModuleHandle ;
test eax, eax ;
jnz SkipZeros ;
lea ebx, [LLoffset+4] ;
push edi ;
mov LLoffset, ebx ;
call aLoadLibrary ;
mov [ebx-4], eax ; Save it. We'll need later for FreeLibrary
SkipZeros: ;
add edi, 10 ;
mov ebx, eax ; ebx=eax=next library handle
mov edx, [eax+3Ch] ; Get start of the PE header in edx
SZLoop: ;
cmp byte ptr [edi-5], "." ; Ex: GDI32.dll,0,Set....
jz FindAPI ; jmp if edi -> the offset of 1st API name
inc edi ;
jmp SZLoop ; loop again
EndGetProc: ;
;add esp,(0+1)*4 ; restore stack
;.............................................................................................................;
;Register the Main window class ;
mov dword ptr [esp], SM_CYSCREEN ;
mov [esp-(1+0)*4], offset L_CW ;
mov dword ptr [esp-(2+0)*4], SM_CXSCREEN ;
mov [esp-(3+0)*4], offset L_CY ;
mov dword ptr [esp-(4+0)*4], IDI_APPLICATION ;
mov dword ptr [esp-(5+0)*4], 0 ;
mov [esp-(6+0)*4], offset L_CX ;
mov dword ptr [esp-(7+0)*4], IDC_ARROW ;
mov dword ptr [esp-(8+0)*4], 0 ;
mov [esp-(9+0)*4], offset L_Icon ;
sub esp, [(9+0)*4] ;
jmp aLoadCursor ;
L_CW: ;
mov esi, offset Start ;
mov dStack, esp ; save the stack
mov edx, MainW ;
mov ecx, MainH ;
sub edi, edx ;
mov [esp-(6+0)*4], edx ; edx->RECT.right
shr edi, 1 ;
and esi, 0FFFF0000h ;
sub eax, ecx ;
mov wchInstance, esi ;
shr eax, 1 ;
mov [esp-(5+0)*4], ecx ; ecx->RECT.bottom
mov [esp-(8+0)*4], edi ; edi->RECT.left
mov [esp-(7+0)*4], eax ; eax->RECT.top
;Create the main window ;
mov dword ptr [esp-(1+0)*4], 0 ;
mov [esp-(2+0)*4], esi ; esi->hInstance
mov dword ptr [esp-(3+0)*4], 0 ;
mov dword ptr [esp-(4+0)*4], 0 ;
mov dword ptr [esp-(9+0)*4], \ ;
WS_OVERLAPPEDWINDOW or \ ;
WS_VISIBLE ;
mov [esp-(10+0)*4], offset ProgName ;
mov [esp-(11+0)*4], offset ClassName ;
mov dword ptr [esp-(12+0)*4], 0 ;
mov [esp-(13+0)*4], offset WndProc ; return address
;RegisterClassEx ;
mov [esp-(14+0)*4], offset wccbSize ;
mov [esp-(15+0)*4], offset CreateWindowEx ; return adddress
sub esp, (15+0)*4 ;
jmp aRegisterClassEx ; call API
L_Icon: ;
mov wchCursor, eax ;
jmp aLoadIcon ;
L_CX: ;
mov wchIcon, eax ;
mov wchIconSm,eax ;
jmp aGetSystemMetrics ; call API
L_CY: ;
mov edi, eax ;
jmp aGetSystemMetrics ; call API
;.................................................................................................................... ;
;End of My Internal Buffer ;

WndProc:
cmp esp, dStack ;
jz WinMainWait ;
WinMain: ; msgs are in ASCENDED order
mov edi, [esp+(2+0)*4] ; edi=uMsg->2
mov eax, nMessages ; eax=number of messages
xor edx, edx ; edx=0
WinMainMin: ;
mov ebx, eax ;
add eax, edx ;
shr eax, 1 ;
cmp edi, [MainMessages+eax*8] ;
jz WinMainExec ;
WinMainLoop: ;
dec eax ;
jc WinMainMin ;
;To_max: ;
lea edx, [eax+2] ;
lea eax, [eax+ebx+2] ;
shr eax,1 ;
mov esi, [MainMessages+eax*8] ;
cmp ecx, esi ;
jz DefWindowProc ; call API
mov ecx, esi ;
cmp edi, esi ;
jnz WinMainLoop ;
WinMainExec: ;
; [esp]=last ret address->WndProc ;
; [esp+4]=hwnd, [esp+8]=umsg, [esp+12]=wParam, [esp+16]=lParam;
;
jmp dword ptr [MainMessages+eax*8+4] ;
WinMainExit: ;
add esp, (4+1)*4 ; clear the stack
WinMainWait: ;
lea ecx, [esp- (4+0)*4] ; loading auto stack
mov [esp-(5+0)*4], offset WndProc ; last return -> WndProc
mov dword ptr [esp-(6+0)*4], 0 ; 3 zeros are parameters
mov dword ptr [esp-(7+0)*4], 0 ; of GetMessage
mov dword ptr [esp-(8+0)*4], 0 ;
mov [esp-(9+0)*4], ecx ; ecx-> offset MSG struc
mov [esp-(10+0)*4], offset WinMain ; return-> WinMain
;
mov esi, cObjects ;
mov dword ptr [esp-(11+0)*4], MWMO_ALERTABLE ;
mov dword ptr [esp-(12+0)*4], QS_ALLINPUT ;
mov dword ptr [esp-(13+0)*4], INFINITE ;
mov [esp-(14+0)*4], offset lphObjects ;
mov [esp-(15+0)*4], esi ;
mov [esp-(16+0)*4], offset WinObj ; return address
sub esp, (16+0)*4 ;
jnz MsgWaitForMultipleObjectsEx ;
WinObj: ;
sub eax, WAIT_OBJECT_0 ;
cmp eax, esi ; esi->cObjects
jz GetMessage ;
DoObjects: ;
add esp,(10+0)*4 ;
mov eax, eax ;
;
;
jmp WinMainWait ;
;.................................................................................................................... ;
OnCommand: ;
mov eax, nComMessagesID ; eax->number of identificators
movzx edx, word ptr [esp+12+4] ; edx-> LOWORD wParam
OnComm_1: ; item, control, or accelerator
dec eax ; identificator
jl OnComm_2 ; l=not found and exit
cmp [CommandMessages +eax*8], edx ; see if is the correct ident.
jnz OnComm_1 ;
jmp dword ptr [CommandMessages+eax*8+4] ; call correct procedure
OnComm_2: ;
add esp, 4 ; clear return address
jmp DefWindowProc ; call API
;.................................................................................................................... ;
OnSysCommand: ;
mov eax, [esp+(3+0)*4] ; 3->wParam
and eax, 0FFF0h ;
cmp eax, SC_CLOSE ; Alt+F4 or menu item Close
je OnDestroy ;
jmp DefWindowProc ;
;.................................................................................................................... ;
OnSize: ;
jmp DefWindowProc ;
;....................................................................................................................;
;[esp] -> return address ;
;[esp+4] -> hWnd ;
;[esp+8] -> Msg ;
;[esp+12] -> wParam ;
;[esp+16] -> lParam ;
;.................................................................................................................... ;
ALIGN 8 ;
MainMessages DD WM_CREATE, OnCreate ; WM_CREATE=01h
DD WM_DESTROY, OnDestroy ; WM_DESTROY=02h

; DD WM_SIZE, OnSize ; WM_SIZE=05h
DD WM_PAINT, OnPaint ; WM_PAINT=0Fh
DD WM_CLOSE, OnDestroy ; WM_CLOSE=10h
DD WM_QUIT, OnDestroy ; WM_QUIT=12h

; DD WM_GETMINMAXINFO, OnGetminmaxinfo ; 24h


; DD WM_DRAWITEM, OnDrawitem ; WM_ DRAWITEM =2Bh
; DD WM_MEASUREITEM, OnMEASUREITEM ; WM_MEASUREITEM=2Ch
; DD WM_NOTIFY, OnNotify ; WM_NOTIFY =4Eh
; DD WM_CONTEXTMENU, OnInitMenu ; 7Bh
; DD WM_DISPLAYCHANGE,OnDisplayChange ; 7Eh
; DD WM_NCLBUTTONDOWN, OnNclbuttondown ; 0A1h
; DD WM_COMMAND, OnCommand ; WM_COMMAND=111h
DD WM_SYSCOMMAND, OnSysCommand ; WM_SYSCOMMAND =1112h

; DD WM_TIMER, OnTimer ;WM_TIMER = 113h
; DD WM_INITMENU,OnInitMenu ;116h
; DD WM_INITMENUPOPUP, OnInitMenuPop ;117h
; DD WM_MENUSELECT, OnMenuSelect ;11Fh
; DD WM_ENTERIDLE, OnMenuIdle ; 121h
; DD WM_MOUSEMOVE, OnMouseMove ; WM_MOUSEMOVE=200h
; DD WM_LBUTTONDOWN, OnMouseMove_1 ; WM_LBUTTONDOWN=201h
; DD WM_RBUTTONDOWN, OnRbuttonDown ; WM_RBUTTONDOWN=204h
; DD WM_EXITMENULOOP, OnExitMenu ;212h
nMessages DD ($-MainMessages)/8 ;
;.....................................................................................................................;
CommandMessages DD 670, OnDestroy ; button Cancel
; DD 671, OnBrowse ; button Browse
; DD 672, OnServer ; button Server
; DD 673, OnMinimize ; button Minimize
; DD 674, OnDestroy ; button Close
nComMessagesID DD ($- CommandMessages)/8 ;
;.....................................................................................................................;
OnDestroy: ;
mov edi, offset LL1+4 ; lp to LoadLibrary handles table
mov ebp, [edi-4] ; get LoadLibrary handle
DesLoop: ;
push ebp ; free libraries
call FreeLibrary ;
mov ebp, [edi] ; get LoadLibrary handle
add edi, 4 ;
test ebp, ebp ;
jnz DesLoop ;
jmp ExitProcess ; Exit
;...................................................................................................... ;
OnMinimize: ;
mov eax, hWnd ;
push 0 ;
push SC_MINIMIZE ;
push WM_SYSCOMMAND ;
push eax ;
call PostMessage ; call API
jmp WinMainExit
;...................................................................................................... ;
OnPaint: ;
sub esp, sizeof PAINTSTRUCT + sizeof RECT
mov ebx,esp
push ebx ;
push hWnd ;
push ebx ;
push hWnd ;
call aBeginPaint ;
mov esi, eax ; esi->hDC

push COLOR_BTNHIGHLIGHT ; light grey color
call aGetSysColor ; call proc
push eax
push esi
call SetTextColor

push TRANSPARENT
push esi
call SetBkMode
lea ebx, [esp+36]
push ebx
push hWnd
call GetClientRect

push DT_VCENTER ;
push ebx ; ebx-> rect
push -1 ; len of string
push offset szTest ; offset String
push esi ; esi-> DC
call aDrawText ; call proc

call aEndPaint ;
add esp, sizeof PAINTSTRUCT + sizeof RECT ;
xor eax, eax
jmp DefWindowProc

End Start
Posted on 2002-05-31 19:29:28 by buliaNaza
Some of the assumptions here fascinate me, without decompiling every windows API function, you have no way of knowing which registers they do or do not use so the ONLY choice is to observe the arbitrary convention for Windows coding which is to preserve EBX ESI & EDI and ESP and EBP if you handle the stack manually.

The reference to Mavericks question is an interesting one,

=====================
Q: "does anyone have a clue how to find the exact address of the PE-Header of an EXE-File.
=====================

If loading the structure IMAGE_DOS_HEADER for the MZ header is too much work by reading its member e_lfanew, whats wrong with searching for the PE signature ?

Some of this stuff in here has the assumptions of elitism yet there has long been argument for not doing more than you need to do when the bulk of most programs sit there idling and only a small portion actually do any speed critical work.

We all know that REAL MEN PROGRAM IN HEX but there are very few of US left. :)

i wonder what the point is in producing code that is so hard to read when there is so little to gain ? Is there some point to producing the worlds fastest loading common dialog box that is at least a gigasecond faster than the standard system version ? Such technology deserves all the fanfare of a gnats fart.

Regards,

hutch@movsd.com
Posted on 2002-05-31 21:50:26 by hutch--
I'd have to agree hutch--. In the world all the matters is what gets the job done, and everything else is artistic expression. I like expressing myself with ASM. :)
Posted on 2002-05-31 22:01:14 by bitRAKE
;) ;) Hey cmax,
here is another proof WHY...
Posted on 2002-05-31 22:12:53 by buliaNaza
i wonder what the point is in producing code that is so hard to read when there is so little to gain ? Is there some point to producing the worlds fastest loading common dialog box that is at least a gigasecond faster than the standard system version ? Such technology deserves all the fanfare of a gnats fart.


Depends on whos doing it:

"Because I can"

"I want to see if it can be done"

"I want to see if I can do it"

"I want to learn something by trying to do it the hard way"

Personally I think there is some learning value to doing things the hard way. Usually the best lesson you get, is why most people do it the easy way:grin:

Unlike C++, there is no language standard for assembly for the language nazis to harp on. The freedom of assembly.
Posted on 2002-05-31 22:34:32 by ThoughtCriminal
ThoughtCriminal,

I think you have made some very good points here in relation to the motivation that people have for writing many different things but when someone does something AND expects others to do it their way, it becomes a different matter.

I am all for original idea and doing things in different ways but I also allow other to be original with their ideas and do things a different way, not inflict on them the idea that they should be doing things by someone elses way.

Regards,

hutch@movsd.com
Posted on 2002-05-31 23:23:47 by hutch--
I too agree here..

When my com-sci friends ask my why i prefer ASM over any other language, i tell them its because "i have my own personal bag of tricks". :)

Unlike any other language, i define my own tools, macros, equates, templates, etc., witch allows me to make what i want, the way i want. period.

Its like the game "Magic" if anyone is familiar with it. Your suppose to dual with another 'wizard' and each randomly pulls a magic spell from their sache to attack/deffend against the other. With asm, i dont need to take handout "tricks" from the standard C++ guild, i can simply make my own, and become as strong as i choose when "attacking" a coding project. This freedom is what i truely LOVE about MASM over any HLL.

More so, i reciently transcribed a fairly length C++ source to masm, and i was AMAZED at how much redundancey on over delaration of variables that was needed to get the job done. It was soo bad it slowed me down, having to trace thu the code and see if a SCOPED varialbe is nothing more than some other variable somewhere else. Im mean it, it was BAD!... This kinda crap I have no patience for.

I truely appreciate OOP programing, and its Ideals, but i think its long since been corrupted by the 'insta-programmer' training schools and their bosses who trade the size of the progams on the clients HD, to save a buck and let the C++ grinder take care of it... :rolleyes:

/end: rant.
:nan:
Posted on 2002-06-01 00:26:09 by NaN

I'd have to agree hutch--. In the world all the matters is what gets the job done, and everything else is artistic expression. I like expressing myself with ASM. :)
buliaNaza, 'the job' is different for different people. :) What is your job? Why do you like programming the way you do? It's good to hear your motivations - they are not as obvious as they are to you. ;) Good example, btw.


buliaNaza, on WinXP your example takes a long time
to start (10+ seconds!) and uses much memory (1656K)?
Posted on 2002-06-01 01:49:37 by bitRAKE
Originally posted by hutch-- The reference to Mavericks question is an interesting one,

=====================
Q: "does anyone have a clue how to find the exact address of the PE-Header of an EXE-File.
=====================
Really, I never ever asked that.. but it's ok++ anyway. ;)
Posted on 2002-06-01 05:37:41 by Maverick