flat assembler
Message board for the users of flat assembler.
Index
> Windows > Learning Win32 programming Goto page 1, 2, 3 Next |
Author |
|
AsmGuru62 20 Apr 2012, 13:49
I suggest take the 'English PDF' from here:
http://www.winprog.org/tutorial/ It starts from the very beginning and code in the book is C code. But it can easily translated into ASM. |
|||
20 Apr 2012, 13:49 |
|
dancho 20 Apr 2012, 16:40
like I said in other thread ,
for the start psdk and Iczelion is enough, go to the lesson 3,it is very simple,read it,understand it ,look for info in sdk, ( Windowing section is first I can think of ) ,and ask questions... gl |
|||
20 Apr 2012, 16:40 |
|
mindcooler 20 Apr 2012, 19:06
Here's my take on a GUI hello world:
http://files.sys5.se/hellogui.zip Search msdn (with Google, it's faster) for the api calls made. _________________ This is a block of text that can be added to posts you make. |
|||
20 Apr 2012, 19:06 |
|
Inagawa 21 Apr 2012, 08:26
Thanks a lot for all the suggestions and the code sample. But mindcooler, what is the virtual for? I've checked the documentation, but to be honest, I'm none the wiser.
Code: ;@ WindowProc: virtual at esp+8 .wmsg rd 1 end virtual What do you gain by this? If I understand correctly, .wmsg becomes a synonym for ESP+8. Why not just do a .wmsg equ ESP+8? At least it appears to work the same as if I use a .wmsg equ esp+8. Also, one thing that has been going through my mind. There is no WinMain, anywhere. Does windows require WinMain, does FASM create it for me? |
|||
21 Apr 2012, 08:26 |
|
AsmGuru62 21 Apr 2012, 11:32
WinMain is provided for you by a C/C++ compiler.
FASM has no such ability. You can get parameters for WinMain by using APIs. Code: ; ; WinMain (hInstance, hPrevInstance, pszCmdLine, iCmdShow) ; invoke GetModuleHandle, 0 mov [hInstance], eax ; ; hPrevInstance is never needed in Win32 (it was needed in Win16) ; invoke GetCommandLineA mov [pszCmdLine], eax ; ; iCmdShow is needed in some rare cases. It is a parameter ; usually passed to ShowWindow to display main application ; window for the first time. Just pass SW_NORMAL for now. ; If you really need this parameter -- use GetStartupInfo API to get it. ; So, basically, you have no need for WinMain. P.S. I use 'virtual' for structures. There is a MASM-born macro struct/ends, which allows to use structures, but I am not using it because the type of the element in a structure can be only one of types defined by FASM, like DD,DW,DB, etc. 'virtual' however allows to use a type alias, which makes code much more readable. For example: Code: HWND equ dd HFONT equ dd PRECT equ dd CHARS equ rb ... virtual at 0 OBJECT1: .pRect1 PRECT ? .hFont HFONT ? .path CHARS 256 .size = $ end virtual ; ; at this point the OBJECT1 can be used as a structure. ; you can get it size by using OBJECT1.size and access its members by using ; the proper expression with a member name: ; mov esi, ... ; <-- load address of a structure into a register mov eax, [esi + OBJECT1.hFont] ; Load the font handle ; ; or use it in API calls without loading it into a register ; invoke GetClientRect, [hWnd], [esi + OBJECT1.pRect] ; |
|||
21 Apr 2012, 11:32 |
|
l_inc 21 Apr 2012, 12:49
AsmGuru62
Quote: the type of the element in a structure Not true. Also other structures and unions can be a field type. And the aliasing can be done in a very similar way: Code: struc HWND [args] { common . dd args } struc HFONT [args] { common . dd args } struc PRECT [args] { common . dd args } struc CHARS [args] { common . rb args } struct OBJECT pRect1 PRECT ? hFont HFONT ? path CHARS 256 ends Furthermore struct allows you to define OBJECT variables (not just the labels like OBJECT.pRect1), make them be field types of other structures, defines sizeof for every field and for the whole structure. Thus it's a very bad suggestion to avoid using struct. |
|||
21 Apr 2012, 12:49 |
|
Inagawa 21 Apr 2012, 13:18
Shouldn't the size be ".size = $ - OBJECT1" or something like that?
Anyway, using structures it bad or good? And what exactly do you mean by object variables? How are object variables different from labels, they both point to a chunk of memory, no? |
|||
21 Apr 2012, 13:18 |
|
l_inc 21 Apr 2012, 13:54
Inagawa
Quote: Shouldn't the size be ".size = $ - OBJECT1" It should. And it is. Because OBJECT1 equals to zero: virtual at 0 means, that the virtual addressing space will start addressing from zero. Quote: Anyway, using structures it bad or good? As for me, using struct (note the difference between struc and struct) is very handy. Quote: And what exactly do you mean by object variables? Defining a variable of the structure type OBJECT is the following: Code: ;a structure with defined fields: obj1 OBJECT 0x401234,2,'Hello, world!' ;a structure with undefined fields obj2 OBJECT This allocates memory for obj1 and obj2 and defines labels to this memory obj1.pRect1, obj2.pRect1 and so on. Both is impossible with the approach of AsmGuru62. Quote: How are object variables different from labels, they both point to a chunk of memory, no? No. Variables do not point. They are those chunks of memory. A label itself does not have to point to a valid location. So the definition: Code: struct OBJECT
pRect1 PRECT ?
hFont HFONT ?
path CHARS 256
ends defines a number of labels zero-based labels OBJECT.pRect1, OBJECT.hFont, OBJECT.path. Neither of them points to a valid location. But those a very useful, when working with register-based structures, like mov eax, [esi + OBJECT1.hFont] from the AsmGuru62's example. The above definition also defines numeric constants: sizeof.OBJECT, sizeof.pRect1, sizeof.hFont and sizeof.path. And as I said OBJECT can also become a field type of some other structure (also impossible with the AsmGuru62's approach). |
|||
21 Apr 2012, 13:54 |
|
mindcooler 21 Apr 2012, 13:58
Inagawa wrote: What do you gain by this? If I understand correctly, .wmsg becomes a synonym for ESP+8. Why not just do a .wmsg equ ESP+8? As I'm only using .wmsg in this example you can do it with a somple equ, but if you have several consecutive aliases, then virtual makes it easier by auto-increasing the offset; I only found an example with two parameters, but anyway Code: WindowProc: virtual at esp+8 .wmsg rd 1 .wp rd 1 end virtual Edit: Found some more real-life examples: Code: virtual at ebp w1 rq 1 w2 rq 1 w3 rq 1 w4 rq 1 end virtual virtual at esi x1 rq 1 x2 rq 1 x3 rq 1 x4 rq 1 end virtual lea edi,[w3] fld [x3] Quote: 00401503 |. 8D7D 10 LEA EDI,[EBP+10] _________________ This is a block of text that can be added to posts you make. Last edited by mindcooler on 21 Apr 2012, 14:11; edited 1 time in total |
|||
21 Apr 2012, 13:58 |
|
l_inc 21 Apr 2012, 14:08
Inagawa
Quote:
This code is in fact equivalent to Code: label .wmsg dword at esp+8 So there is a label definition. The label is register-based and bound to the dword size. In contrast .wmsg equ ESP+8 does not define any labels (and btw. is resolved at preprocessing stage). So there're a lot of differences, but the most important are probably that .wmsg becomes visible and interfering with the following code (after the end of the procedure, i.e. after a new global label is defined), and e.g. push [.wmsg] would only compile in the first case, because then the label has a known size (dword). |
|||
21 Apr 2012, 14:08 |
|
Inagawa 21 Apr 2012, 14:11
Thank you guys. I'll try to wrap my head around all of this new info and come back to you on this.
|
|||
21 Apr 2012, 14:11 |
|
dancho 21 Apr 2012, 19:12
@Inagawa
maybe would be easier to understand if you read this first : http://flatassembler.net/docs.php?article=win32#1.1 |
|||
21 Apr 2012, 19:12 |
|
AsmGuru62 22 Apr 2012, 14:36
@l_inc: very nice! Thanks! I did not know that it can be done.
I generate some of my code with IDE. So, if I need to declare an object within the other object IDE does this: Code: BYTES equ rb ... virtual at 0 OBJECT2: .chunk1 BYTES OBJECT1.size .chunk2 BYTES OBJECT1.size .chunk3 BYTES OBJECT1.size end virtual and then to access it I point register to the field: Code: ; ; EBX points to OBJECT2 ; lea esi, [ebx + OBJECT2.chunk3] mov eax, [esi + OBJECT1.hFont] or sometimes I use a combined offset, like so: Code: mov eax, dword [ebx + OBJECT1.hFont + OBJECT2.chunk3] Of course, it is a little inconvenient. Proper structs provide easier coding, but I have been coding like that for years. It will be hard to re-learn a new way. The new IDE I am writing will have easier way of coding, like: Code: mov eax, this.chunk3.hFont call this.OnCreate (loc.vectCells, loc.uiNumCells, glb.hHeap, L"HELLO") And the code generator runs through this script doing stuff, like - putting UNICODE text "HELLO" into data section, - calling virtual methods, - passing local and global variables, - etc. |
|||
22 Apr 2012, 14:36 |
|
bzdashek 22 Apr 2012, 19:02
AsmGuru62 wrote:
Wow, this.going to be a great thing. Btw, while searching for the ways to trap WM_KEYDOWN event, I ran into some of your replies on "programmers heaven", dated 19 nov 2003 ~ 23 nov 2003. You were suggesting to a person subclass some procedure, and he was grateful. That might bring some old memories: http://www.programmersheaven.com/mb/windows/225781/226489/re-wm_keydown-never--more/?S=B10000 Sorry for the off-topic. |
|||
22 Apr 2012, 19:02 |
|
AsmGuru62 22 Apr 2012, 21:26
Nice.
programmersheaven got really disorganized a couple of years ago. My password got reset for some reason -- I sent a request to change password, but the site was not working properly and new password (sent to me) was also not working. I tried few things, like waiting for some time and logging in again -- no luck. It looked like new password(s) were expiring in, like, 5 sec. So, my help on PH ended at that point. New IDE will be indeed interesting, but it will be good for new projects. If you have some old code -- IDE will not be of much use, because it will have a different approach to code. Also, I am writing a form designer, so dialogs (or forms) can be created quickly in visual manner. |
|||
22 Apr 2012, 21:26 |
|
Inagawa 23 Apr 2012, 19:40
Hi there, I get a weird error. Guru, you told me that labels are unique to their procedure, then why am I getting an error? What have I overlooked?
Code: proc !IsLetter uses edx, Character ; ; Making all the characters lowercase makes evaulation ; easier ; stdcall !ToLowercase, [Character] mov ecx, 26 mov edx, 97 SearchCharacters: cmp eax, edx je CharacterFound inc edx loop SearchCharacters ; ; If the [Character] is not a letter, return 0 ; mov eax, 0 ret CharacterFound: mov eax, 1 ret endp Is !IsNumber, okay? It's telling me its labels SearchCharacters and CharacterFound are both already defined. Code: proc !IsNumber uses edx, Character mov ecx, 10 mov edx, 48 SearchCharacters: cmp [Character], edx je CharacterFound inc edx loop SearchCharacters ; ; If the [Character] is not a number, return 0 ; mov eax, 0 ret CharacterFound: mov eax, 1 ret endp The first error I get is that CharacterFound is already defined here in !IsAlphanumeric. When I exclude this procedure from the program, there aren't any conflicts. I fail to see what is wrong here.. Code: proc !IsAlphanumeric uses edx, Character stdcall !IsLetter, [Character] mov edx, eax stdcall !IsNumber, [Character] or edx, eax cmp edx, 1 je CharacterFound mov eax, 0 ret CharacterFound: mov eax, 1 ret endp Thanks for any help, it's probably something completely silly that I've overlooked. |
|||
23 Apr 2012, 19:40 |
|
AsmGuru62 23 Apr 2012, 21:20
to get labels differentiated in diff. procs -- you need to prefix these labels with a dot (.).
Just replace "CharacterFound:" with ".CharacterFound:" and of course if you jump or call this label - use the dot too, like so: jmp .CharacterFound |
|||
23 Apr 2012, 21:20 |
|
Inagawa 23 Apr 2012, 21:28
Thanks, that solved it. I thought labels are unique no matter the dot - guess I was wrong.
|
|||
23 Apr 2012, 21:28 |
|
AsmGuru62 23 Apr 2012, 22:01
You can even jump into the middle of a procedure if needed, like so:
Code: proc1: ... jmp proc2.LABEL1 ... ret proc2: ... .LABEL1: ... ret If both procedures have the same ending code, you can do that to make the code smaller, but watch out for local variables - they must be the same size for both procedures. If you remember the FORTRAN language -- it has the same ability with ENTRY statement. |
|||
23 Apr 2012, 22:01 |
|
Goto page 1, 2, 3 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.