flat assembler
Message board for the users of flat assembler.
Index
> Windows > Win32 calls. Register usage? Goto page Previous 1, 2, 3, 4 ... 9, 10, 11 Next |
Author |
|
f0dder 07 Jun 2009, 08:35
Azu wrote:
_________________ - carpe noctem |
|||
07 Jun 2009, 08:35 |
|
Azu 07 Jun 2009, 08:38
f0dder wrote:
|
|||
07 Jun 2009, 08:38 |
|
LocoDelAssembly 07 Jun 2009, 14:35
Quote:
Quote: I did. Couldn't find any other functions in Windows that don't clean up after themselves. Since you obviously know more then me, why don't you just save both of us time by naming them (if there really are any others)? Last edited by LocoDelAssembly on 07 Jun 2009, 14:43; edited 1 time in total |
|||
07 Jun 2009, 14:35 |
|
revolution 07 Jun 2009, 14:39
Azu wrote: Couldn't find any other functions in Windows that don't clean up after themselves. Since you obviously know more then me, why don't you just save both of us time by naming them (if there really are any others)? |
|||
07 Jun 2009, 14:39 |
|
Azu 07 Jun 2009, 15:23
LocoDelAssembly wrote:
LocoDelAssembly wrote:
revolution wrote:
revolution wrote: You didn't really believe that MS invented CDECL just for one function? Did you? And if not.. then all the more reason for it to be done right. |
|||
07 Jun 2009, 15:23 |
|
revolution 07 Jun 2009, 15:36
Azu wrote: Yes [I did think MS invented CDECL just for wsprintf]. Azu wrote: And if not.. then all the more reason for it to be done right. |
|||
07 Jun 2009, 15:36 |
|
Azu 07 Jun 2009, 15:43
revolution wrote:
revolution wrote:
revolution wrote: you don't have to use it if you don't want to. Ignore it, forget about it, don't think about it, don't use it, pretend it doesn't exist, there, problem solved. |
|||
07 Jun 2009, 15:43 |
|
revolution 07 Jun 2009, 15:55
But you said you thought cdecl was invented by MS for this one function. It would seem reasonable to search google for cdecl history, not for more Windows functions. That way your assumption could have be quickly confirmed or refuted (in this case refuted).
One function is vararg, the other is not. vararg is not supported by stdcall, so the function can't be stdcall, it falls outside the stdcall standard. You can't implement vararg in stdcall, not possible with HLL code, can't be done. Tricky asm code could do it, but then that is not HLL anymore, so MS won't do it, not sensible to do, not portable to other systems. As for the non-vararg version: no problem, falls within stdcall standard, easy in HLL. Nothing tricky required. But now YOU have to allocate memory and things to pass the arguments to the function, makes it not so convenient for you. |
|||
07 Jun 2009, 15:55 |
|
LocoDelAssembly 07 Jun 2009, 16:04
Quote:
At least for MSVCRT.DLL I'm sure it comes on a Win95 OSR2 without installing anything else. Yet, even if you were right you are not proving Microsoft invented cdecl at all. They merely copied sprintf to the Windows API and prefixed it with "w" (so you can call it even if you are using C language with no collision problems). cdecl had already solved the problem of handling varargs so they didn't invented a new calling convention to handle this (which would have defeated the purpose a bit because the idea was to copy the sprintf function from C language). |
|||
07 Jun 2009, 16:04 |
|
Azu 07 Jun 2009, 16:27
revolution wrote: But you said you thought cdecl was invented by MS for this one function. It would seem reasonable to search google for cdecl history, not for more Windows functions. That way your assumption could have be quickly confirmed or refuted (in this case refuted). revolution wrote: One function is vararg, the other is not. vararg is not supported by stdcall, so the function can't be stdcall, it falls outside the stdcall standard. You can't implement vararg in stdcall, not possible with HLL code, can't be done. Tricky asm code could do it, but then that is not HLL anymore, so MS won't do it, not sensible to do, not portable to other systems. ;Data PointerToString db "world",0 PointerToInput "Hello %s! %i is the answer ",0 PointerToOutput rb 255 ;Callee push PointerToString push 42 push PointerToInput push PointerToOutput call wsprintf ;Called wsprintf: pop ecx pusha pop edi pop esi LoadLoop lodsb test al,al jz NullChar cmp al,"%" je FormatChar stosb jmp LoadLoop FormatChar: lodsb cmp al,"i" jne StringChar pop eax ;put integer to ascii code here.. to lazy to write it, and doesn't matter for example anyways.. jmp LoadLoop StringChar: mov edx,esi pop esi StringCharLoop lodsb test al,al jz StringCharLoopNull stosb jmp StringCharLoop StringCharLoopNull mov esi,edx jmp LoadLoop NullChar: popa jmp ecx Surely that way is more easy for a HLL to generate then the stuff it's currently doing? And then the stack is cleaned up after itself, and it is still vararg, and using the normal standard, and not having to piggy back off of the other function.. revolution wrote: As for the non-vararg version: no problem, falls within stdcall standard, easy in HLL. Nothing tricky required. But now YOU have to allocate memory and things to pass the arguments to the function, makes it not so convenient for you. mov edi, edi push ebp mov ebp, esp lea eax, [ebp+arglist] push eax ; arglist push [ebp+arg_4] ; LPCWSTR push [ebp+arg_0] ; LPWSTR call wvsprintfW pop ebp retn And anyways what I meant was, vararg is fine, the problem is that it doesn't clean up after itself so programs must have ons of add esp,XXX all over it for no reason. Very bad standard! Last edited by Azu on 07 Jun 2009, 16:42; edited 2 times in total |
|||
07 Jun 2009, 16:27 |
|
revolution 07 Jun 2009, 16:34
Your code won't work. edi is the return address and you overwrite your code with stosb. The 'ret' jumps to somewhere not where you expect.
I think you clearly don't understand HOW an HLL works. Like I said, and it is not a mistake, HLL using a stdcall interface cannot implement a vararg function. Once you understand that you will see WHY wsprintf cannot be stdcall. |
|||
07 Jun 2009, 16:34 |
|
Azu 07 Jun 2009, 16:38
revolution wrote: You code won't work. edi is the return address and you overwrite your code with stosb. The 'ret' jumps to somewhere not where you expect. revolution wrote: I think you clearly don't understand HOW an HLL works. Like I said, and it is not a mistake, HLL using a stdcall interface cannot implement a vararg function. Once you understand that you will see WHY wsprintf cannot be stdcall. Edit: I went back and fixed the stupid example so it should work right now And with that I make my leave. Can hardly keep my eyes open lol. I'll be back tomorrow okay |
|||
07 Jun 2009, 16:38 |
|
revolution 07 Jun 2009, 16:44
Please read up about HOW and HLL will implement the vararg solution you suggest. There is no calling standard that supports vararg with auto-stack cleanup, so therefore, no HLL can implement it. IF there is an HLL that has access to the stack register then it may be possible to do, but I don't know of any HLL that allows such thing without recourse to embedded assembly.
BTW: a better asm solution is already presented in this thread early on. But you can't do these things in an HLL. Okay, really, no bluff, HLLs just can't do it. Last edited by revolution on 07 Jun 2009, 16:50; edited 1 time in total |
|||
07 Jun 2009, 16:44 |
|
Azu 07 Jun 2009, 16:47
P.S. I never directly accessed the stack register (esp) or even the frame register (ebp) anywhere in my example. Yet the way it is doing it now, with the HLL, directly accesses them both, see
"mov edi, edi push ebp mov ebp, esp lea eax, [ebp+arglist] push eax ; arglist push [ebp+arg_4] ; LPCWSTR push [ebp+arg_0] ; LPWSTR call wvsprintfW pop ebp retn" Last edited by Azu on 07 Jun 2009, 16:49; edited 1 time in total |
|||
07 Jun 2009, 16:47 |
|
revolution 07 Jun 2009, 16:49
'pop ecx' is direct stack manipulation. In HLL, how will you make it do a 'pop ecx'?
|
|||
07 Jun 2009, 16:49 |
|
Azu 07 Jun 2009, 16:52
Dunno but they do. Try this
mov edi,esp push 1 call Sleep sub edi,esp jnz Sleepy int3 Sleepy: push -1 call Sleep It will crash every time. If the normal Windows functions didn't pop the args off, it would just sleep forever. Okay I'm REALLY going to bed now, good night |
|||
07 Jun 2009, 16:52 |
|
LocoDelAssembly 07 Jun 2009, 16:53
Oh, you think that the number of varargs can be calculated from the fmt?
What would you think it could happen here then? Code: wsprintf(buff, person.showAge ? "Person %u works at %s, and is %u years old" : "Person %u works at %s. Age can't be disclosed",\ person.id, person.department, person.age); Code: . . . fmtTab dd fmtNoAge, fmtAge fmtAge db "Person %u works at %s, and is %u years old", 0 fmtNoAge db "Person %u works at %s. Age can't be disclosed", 0 . . . cmp [person.printAge], 0 setne cl movzx ecx, cl mov ecx, [fmtTab+ecx*4] ccall wsprintf, buff, ecx, [person.id], [person.department], [person.age] . . . |
|||
07 Jun 2009, 16:53 |
|
revolution 07 Jun 2009, 17:03
Azu wrote: Dunno but they do. Try this All of your code above is fine for assembly programmers, but HLL imposes restrictions that make some things impossible to do. |
|||
07 Jun 2009, 17:03 |
|
Borsuc 07 Jun 2009, 23:51
f0dder wrote: No, they went with standard cdecl. Actually, it could have small speed improvements in some cases. But it's still bad design in my opinion. (just for the record, I don't blame MS, I blame cdecl). On second thought, vararg functions (that is, the functions themselves, not the code that calls them) should be made in asm anyway _________________ Previously known as The_Grey_Beast |
|||
07 Jun 2009, 23:51 |
|
Goto page Previous 1, 2, 3, 4 ... 9, 10, 11 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.