I'v just started using MASM and from what I can see any APIs are CALL&JMP. If I didn't explain it right heres an example from my app:
00401002 |. E8 95000000 CALL 0040109C
and at 0040109C is this:
0040109C $-FF25 08204000 JMP DWORD PTR DS:[<&kernel32.GetModuleHa>; kernel32.GetModuleHandleA
Is there a reason MASM does this? Is there any way to disable it because from what i can see it uses more space and slows down execution :|
00401002 |. E8 95000000 CALL 0040109C
and at 0040109C is this:
0040109C $-FF25 08204000 JMP DWORD PTR DS:[<&kernel32.GetModuleHa>; kernel32.GetModuleHandleA
Is there a reason MASM does this? Is there any way to disable it because from what i can see it uses more space and slows down execution :|
If there is alot of calls made to the same function, it actually saves space. ;)
I don't think there is any way to disable it.
I don't think there is any way to disable it.
It's usually done like this, and it's not really a problem. It's also easy to calculate how many calls you need before it saves space, iirc it's 5.
You can get direct "call dword ptr __imp_function" by muzzing around with the header files, iirc there's even a tool in the MASM32 to generate those "direct protos".
You can get direct "call dword ptr __imp_function" by muzzing around with the header files, iirc there's even a tool in the MASM32 to generate those "direct protos".
I don't think it would save space. correct me if I'm wrong but a "direct" call is 1 WORD + 1 DWORD so 6 bytes. However, With a CALL/JMP the call is 1 byte + 1 DWORD so thats 5 bytes. Then you have the 1 WORD + 1 DWORD for the JMP which makes 11 (6+5).
And as far as I can tell it would be slower too. I can understand it would save space if you called it a lot. 5 calls would be equal and any extra calls from there would save 1 byte each. But I think speed would be more important. but taking into consideration would need to call EVERY API atleast 5 times then most apps would not actually benefit from this (they would lose speed AND file space).
P.S could you give me an example of how to use __imp_function? I guess you can't use invoke for this but thats hardly a loss if I make a small app.
And as far as I can tell it would be slower too. I can understand it would save space if you called it a lot. 5 calls would be equal and any extra calls from there would save 1 byte each. But I think speed would be more important. but taking into consideration would need to call EVERY API atleast 5 times then most apps would not actually benefit from this (they would lose speed AND file space).
P.S could you give me an example of how to use __imp_function? I guess you can't use invoke for this but thats hardly a loss if I make a small app.
"call " - FF15 imm32 - 6 bytes
"call jmp_import" - E8 imm32 - 5 bytes
the 5-byte call has an additional overhead of FF25 imm32, 6 bytes. We'll leave out the 4-byte import since it's present for both methods.
So, we solve the equation "6 + 5x < 6x", which gives "x > 6" - in other words there's a break-even sizewise for 6 calls, after that the "call jmp_import" starts saving a bit. Of course this is utterly irrelevant - the exe size will hardly be affected whichever method you use.
Same goes for speed, you'll gain practically nothing by this. If there was even a slight chance of gaining anything, the person putting so little code in a function that this matters, should be shot for ?ber-bad design :)
You can use invoke, you just need proper protos... let me see if I can dig up the info.
"call jmp_import" - E8 imm32 - 5 bytes
the 5-byte call has an additional overhead of FF25 imm32, 6 bytes. We'll leave out the 4-byte import since it's present for both methods.
So, we solve the equation "6 + 5x < 6x", which gives "x > 6" - in other words there's a break-even sizewise for 6 calls, after that the "call jmp_import" starts saving a bit. Of course this is utterly irrelevant - the exe size will hardly be affected whichever method you use.
Same goes for speed, you'll gain practically nothing by this. If there was even a slight chance of gaining anything, the person putting so little code in a function that this matters, should be shot for ?ber-bad design :)
You can use invoke, you just need proper protos... let me see if I can dig up the info.
Here's an example of how I do it:
That lets you use INVOKE, but a simple
will let you use CALL (but not INVOKE)
prwsprintf TYPEDEF PROTO C :DWORD, :VARARG
pwsprintf TYPEDEF PTR prwsprintf
EXTERNDEF _imp__wsprintfA:pwsprintf
wsprintf TEXTEQU <_imp__wsprintfA>
That lets you use INVOKE, but a simple
EXTERNDEF _imp__wsprintfA:DWORD
will let you use CALL (but not INVOKE)