flat assembler
Message board for the users of flat assembler.
Index
> Windows > Confused about register preserving |
Author |
|
newbie 09 Jul 2004, 21:20
I've been trying to learn windows assembly programming and have been using the Iczelion tutorials that Privalov converted to fasm 1.52 format.
So far so good, but I'm a bit confused about register preservation. From what I've read you have to preserve ebx, esi, and edi in callbacks such as the main window proc. In the converted fasm tutorials (at http://board.flatassembler.net/topic.php?t=1482), those registers are used in the main window proc without restoring them at the end. I guess I've obviously got it wrong that they are meant to be saved. Could someone please explain which registers have to be saved and when? Thanks. |
|||
09 Jul 2004, 21:20 |
|
scientica 09 Jul 2004, 21:46
well, as a general rule you should preserve all registers you use (imo), think the secario:
uses some registers calls a fnction or api ok what's the state of the regitsers now? with the api you're told that some registers are always preserved by the API (forgot which ones now), this means that all other registers should be considered tampered with by the funciton/api. There is only two registers you never need/must to preserve, eax and esp. eax is return value and esp is the stack pointer - "break" esp and you'll most likey(read: always) crash your program, and eax is genereally god to set to 0 - to indicate the function did fine. |
|||
09 Jul 2004, 21:46 |
|
newbie 09 Jul 2004, 22:19
pelaillo wrote: Please post the implied tutorial in order to fix it. Well it's most of them in tutfasm.zip from the thread I linked to. The direct URL is http://board.flatassembler.net/download.php?id=756 Anyway here's an example from tut04.asm Code: proc WndProc, hWnd,uMsg,wParam,lParam hdc dd ? ps PAINTSTRUCT rect RECT enter .if [uMsg],e,WM_DESTROY invoke PostQuitMessage, NULL .elseif [uMsg],e,WM_PAINT lea esi,[ps] invoke BeginPaint, [hWnd],esi mov [hdc],eax lea ebx,[rect] invoke GetClientRect, [hWnd],ebx invoke DrawText, [hdc],OurText,-1,ebx,DT_SINGLELINE or DT_CENTER or DT_VCENTER invoke EndPaint, [hWnd],esi .else invoke DefWindowProc, [hWnd],[uMsg],[wParam],[lParam] return .endif xor eax,eax return endp As you can see, ebx and esi are used in that callback proc without being restored. I'm not sure if it's okay or not. This asm stuff is complicated! |
|||
09 Jul 2004, 22:19 |
|
pelaillo 09 Jul 2004, 23:47
You see it well, tutorials go fixed. I am going to take care of them.
If you permit me a counsel: abandon "ifs", "elses" and other HLL constructs to take most control of your code and because is easier to maintain. For example: Code: proc WndProc, hWnd,uMsg,wParam,lParam hdc dd ? ps PAINTSTRUCT rect RECT enter push ebx esi mov eax,[uMsg] ; note 1 cmp eax,WM_PAINT ; note 2 je wm_paint cmp eax,WM_DESTROY je .wm_destroy invoke DefWindowProc, [hWnd],[uMsg],[wParam],[lParam] jmp .finish .wm_destroy: invoke PostQuitMessage, NULL jmp .finish .wm_paint: lea esi,[ps] invoke BeginPaint, [hWnd],esi mov [hdc],eax lea ebx,[rect] invoke GetClientRect, [hWnd],ebx invoke DrawText, [hdc],OurText,-1,ebx,DT_SINGLELINE or DT_CENTER or DT_VCENTER invoke EndPaint, [hWnd],esi .finish: xor eax,eax pop esi ebx return ;note 3 endp Doesn't it look nicer? The notes: note 1: WinProc normally have many compares against uMsg, and comparing against eax let you save some bytes because opcode is shorter. note 2: Your program will have many WM_PAINT messages before a WM_DESTROY so it is beter dispatch it first. note 3: Althrough it is not wrong to have more than one ret for a procedure, it is safer to have only one, mainly because stack balancing when some pop's missing. |
|||
09 Jul 2004, 23:47 |
|
newbie 10 Jul 2004, 09:46
Thanks for the help and for showing how registers are meant to be preserved in a callback. The cmp/je method does look nicer too. The Iczelion win32asm tutorials seem to use a lot of highlevel if/else stuff.
I have one more question regarding register preservation. Is it okay to use ebx esi and edi without preserving them if you're *not* in a callback? For example in WinMain: Code: lea ebx,[msg] @@: invoke GetMessage, ebx,NULL,0,0 or eax,eax jz @f invoke TranslateMessage, ebx invoke DispatchMessage, ebx jmp @b @@: I think that's okay because we're not in a callback, but I just wanted to check that the api's themselves don't change ebx esi or edi either. Is that correct? |
|||
10 Jul 2004, 09:46 |
|
pelaillo 10 Jul 2004, 15:03
Yes. If you are not in a callback, you are worried by your own code. Windows API functions *must* preserve themselves the ebx, esi and edi, is part of the game. For example, when painting to a DC it is common practice to use ebx to store the handle to the DC through all the gdi functions.
However, it is a good idea to preserve those registers in your own procedures if you are going to use a mix of API and them or to work in a team. Everyone is expecting those registers to be preserved. But as general rule, try to avoid relying on API functions, otherwise their bugs will became yours |
|||
10 Jul 2004, 15:03 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.