flat assembler
Message board for the users of flat assembler.
Index
> Windows > call, stdcall, fastcall, invoke confusion; 64-bit style |
Author |
|
revolution 16 Sep 2012, 09:58
I you want to use paameters from the stack then you have to put them there yourself:
Code: proc Proc_exp, hWnd, lpText, lpTitle, bType mov [hWnd],rcx mov [lpText],rdx mov [lpTitle],r8 mov [bType],r9 invoke MessageBox, [hWnd], [lpText], [lpTitle], [bType] Code: proc Proc_exp, hWnd, lpText, lpTitle, bType invoke MessageBox, rcx, rdx, r8, r9 |
|||
16 Sep 2012, 09:58 |
|
farrier 16 Sep 2012, 19:38
Thanks revolution!
So, am I missing something, or is the proc macro not really useful in the 64 bit world since the parameters passed by stdcall or fastcall are not directly accessible in the proc routine. In both examples you provide, the parameters: hWnd; lpText; lpTitle; bType cannot be used directly, and have to be referenced via rcx, rdx, r8, and r9. What is the use of the parameters in the proc macro, other than to reserve space on the stack? Would it be more useful to have the proc macro reference rcx, rdx, r8, and r9 directly? Or should I just define the proc without parameters, and just "call" the proc after manually pushing the parameters to rcx, rdx, r8, and r9? Then once in the proc, use the registers as needed. Thanks for any help. farrier _________________ Some Assembly Required It's a good day to code! U.S.Constitution; Bill of Rights; Amendment 1: ... the right of the people peaceably to assemble, ... The code is dark, and full of errors! |
|||
16 Sep 2012, 19:38 |
|
LocoDelAssembly 16 Sep 2012, 22:44
farrier, the first four params are probably allocated in the so-called spill area, which is a space callers set up for callees to move the parameter registers in there. The reason fasm couldn't automatically take the params by name from the registers is that as soon as you call some other proc/function the registers are garbage (perhaps even your own garbage since you used them to pass the parameters in the call). Since the registers are volatile, you need to manually preserve them.
Take a look at http://flatassembler.net/docs.php?article=win32#1.4 . Perhaps you could write your custom prologue to perform the auto-saving of the parameters onto stack (also try to search both the package and the forum, I think someone already did this). |
|||
16 Sep 2012, 22:44 |
|
farrier 17 Sep 2012, 10:00
Thanks LocoDelAssembly,
I looked thru the docs on the calling conventions for 64 bit, and never saw a requirement that reference to the passed parameters within the called proc had to be thru the stack instead of using the registers directly. It seems as if this was a fasm design decision. I know there is a requirement to reserve stack space corresponding to the number of parameters even if they are not used, but when referencing the parameters passed to a proc, why not use the registers--by default--instead of the stack locations? This is how they are passed to the proc in the first place, and if the registers need to be saved, then they can be saved. Or offer an option to use registers or stack locations! Till then, I'll use a "personalized" approach! instead of the standard proc macros. thanks again!, farrier _________________ Some Assembly Required It's a good day to code! U.S.Constitution; Bill of Rights; Amendment 1: ... the right of the people peaceably to assemble, ... The code is dark, and full of errors! |
|||
17 Sep 2012, 10:00 |
|
revolution 17 Sep 2012, 10:19
the problem is here:
Code: proc Proc_exp, hWnd, lpText, lpTitle, bType xor rcx,rcx ;does rcx now contain proper data for MessageBox? invoke MessageBox, rcx, rdx, r8, r9 |
|||
17 Sep 2012, 10:19 |
|
farrier 17 Sep 2012, 15:56
revolution,
I agree that the registers are more volatile than stack variables, but that is a side effect of the fastcall protocol. The user of the fastcall "invoked" proc must--by definition--be aware of the nature of the registers vs. stack variables. My point is, the values passed to the proc are in the registers and can be used directly and passed to a subsequent proc. If the user of the proc must transfer the register values to the stack, why use fastcall? This seems to defeat the advantage of using the registers to pass parameters. Pass parameters to subsequent procs via the register-defined-parameters and not an assumed stack variable. Thanks for the advice, farrier _________________ Some Assembly Required It's a good day to code! U.S.Constitution; Bill of Rights; Amendment 1: ... the right of the people peaceably to assemble, ... The code is dark, and full of errors! |
|||
17 Sep 2012, 15:56 |
|
revolution 17 Sep 2012, 16:00
For a leaf procedure using registers can be a win. And usually leaf procedures are the most frequently called in any program.
|
|||
17 Sep 2012, 16:00 |
|
AsmGuru62 17 Sep 2012, 20:59
I once noticed a cool pattern in parameters passing.
I had a really big procedure for handling of WM_PAINT message for the syntax-colored editor and there was a lot of locals: rectangles, fonts, colors, etc. all kind of stuff I needed for painting. So, instead of passing stuff around - I was just calling the leaf procedures. The trick is that EBP does not change by a 'naked' CALL instruction. If leaf procedure IS NOT USING the proc macro, then EBP is always set to point to that huge locals block with all the data. So, all I had to do is just CALL my leafs. I had about 15 leaf procedures there and just sometimes I was passing maybe one or two registers - the rest was assumed to be under EBP. And in High-Level Language I had to pass the same values further down the line of leafs (a few times even) - a waste of PUSH-es and stack frame ENTER/LEAVE codes. If I needed a local variable in one of the leafs - I was adding it into the root WM_PAINT locals area. Neat trick, however, if locals area gets large (> 127 bytes) - it bloats the generated code, because an offset gets to be 4 bytes instead of just 1 byte. |
|||
17 Sep 2012, 20:59 |
|
farrier 18 Sep 2012, 05:08
AsmGuru62, revolution
Thanks for the help! I guess I just got used to "the good ole" 32-bit proc and invoke! My take from this: When calling a Windows function, or non-documented 64-bit function, use the "new improved" calling techniques: fastcall; invoke. When designing my own functions and calling them, I will use my own design and calling rules, The ideas proposed by AsmGuru62 make sense and will come in handy! Thanks again, farrier _________________ Some Assembly Required It's a good day to code! U.S.Constitution; Bill of Rights; Amendment 1: ... the right of the people peaceably to assemble, ... The code is dark, and full of errors! |
|||
18 Sep 2012, 05:08 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.