My program is crashing from a write error... apparently I'm trying to write at address 0x33 after a call to socket in the winsock library (wsock32.dll) before I stepover the call to socket, edx = what i want it to be (an address in memory i have read/write permissions to) and after the call to socket edx contains 3. not only that, but ecx has changed as well. I know there is a calling convention that uses ecx/edx to pass arguments (as used in starcraft for example) but the socket call takes it's 3 args off the stack.

sure I could work around this by pushing ecx/edx but i want to know why it is doing this. this is my first project with nasm, I am pretty fluent with masm and have never had this problem before.

;edx is correct at this point
call socket,AF_INET,SOCK_STREAM,0
;edx comes out wrong here ecx too, but ecx gets changed next anyways
  mov ecx, eax
  mov dword,eax


and here's the same code in ollydbg:


100010AC  |> 6A 00          PUSH 0                                  ; /Protocol = IPPROTO_IP
100010AE  |. 6A 01          PUSH 1                                  ; |Type = SOCK_STREAM
100010B0  |. 6A 02          PUSH 2                                  ; |Family = AF_INET
100010B2  |. FF15 58130010  CALL DWORD PTR DS:[<&wsock32.socket>]    ; \socket
100010B8  |. 89C1          MOV ECX,EAX
100010BA  |. 8942 08        MOV DWORD PTR DS:,EAX
Posted on 2008-01-25 13:33:53 by jakor
Don't use edx because the register could be used in the function socket. The only register that you can be sure that its value will not change will be ebp, ebx, edi, esi and esp when you call the api.
Posted on 2008-01-25 17:49:42 by roticv
jakor: this is standard windows calling convention, as roticv is saying. Basically, every time you CALL a piece of code, you should expect EAX, ECX and EDX to be destroyed. Doesn't matter if it doesn't happen on whatever version of windows you're using, you must always treat them this way.

Similarly, you're guaranteed that EBX, ESI, EDI, EBP won't be trashed... and, again, this means you should preserve those registers in your own functions and you must do so in callbacks.
Posted on 2008-01-25 19:16:32 by f0dder
I always just assumed that the standard procedure was to save everything except for eax and I have written many winsock programs with masm and never had a problem (then again, i wasn't trying to save ecx/edx either... =p)  for all of my functions that touched anything except eax i always had uses registers... thank you for clarifying this. This may actually explain a couple other rare bugs I've had in my projects now that i think about it.
Posted on 2008-01-25 22:56:01 by jakor
There's a couple of other rules as well: if you STD you should also CLD before returning, ESP should always be aligned, structures should be aligned, and some more.

There should be a wiki entry about this, somewhere :)
Posted on 2008-01-26 06:32:50 by f0dder
Actually the standard procedure was to save only ebp, esp, edi, esi and ebx. Most people usually end up with weird bugs because they didn't realise this. Glad you found out about it before you pull out all of your hair.  ;)
Posted on 2008-01-26 07:33:44 by roticv
Also, notice that "preserving" the registers don't mean you have to blindly push/pop them, only if you're actually modifying those registers (to avoid senseless discussions from the past ;)).

But, again, for EAX/ECX/EDX, always assume they're trashed when you call external code.
Posted on 2008-01-26 07:42:24 by f0dder
what about a pushf-popf i know this saves more than you need, but what's the cost of this?
Posted on 2008-01-29 23:47:14 by jakor
Dunno what pushf/popf is like speedwise, to be honest, but outside of pretty specific driver code, I wouldn't use pushf/popf but just follow the "if you STD, CLD before exit" rule.
Posted on 2008-01-30 04:07:03 by f0dder
and pushfd / popfd wont preserve the registers.. only push <register> or pushad
Posted on 2008-01-30 11:06:29 by evlncrn8