In the first tutorial of Iczelion's ASM tutorials, the following is used to explain the C calling convention:
In the last line, ADD SP,12 , where is the 12 coming from? Thanks.
push ; Push the third parameter
push ;Followed by the second
push ; And the first
call foo
add sp, 12 ; The caller balances the stack frame
In the last line, ADD SP,12 , where is the 12 coming from? Thanks.
In the first tutorial of Iczelion's ASM tutorials, the following is used to explain the C calling convention:
push ; Push the third parameter
push ;Followed by the second
push ; And the first
call foo
add sp, 12 ; The caller balances the stack frame
In the last line, ADD SP,12 , where is the 12 coming from? Thanks.
Each "push" in that code involves 4-byte values, and there are 3 of them, so instead of using "pop", you can just add 12 (4*3) to the Stack Pointer register (SP) and it balances it out :)
As for stack specific stuff... it is like a stack of papers, the last one you put on top of the stack is the first one that comes off of it.
after using stack you have to restore pointer to it top (esp)
you can do this in some ways:
1. do pop same time as push
push a
push b
...
pop ecx (just to restore stack)
pop ecx
2.if you do not need these values in stack you can just correct stack with direct correcting esp:
push a ; (esp=esp-4)
push b ; (esp=esp-4)
...
add esp,8 ; (-> add esp,4*count_of_pushed_dwords)
2a.
mov edi,esp
push a
push b
...
mov esp,edi
now about calling:
1.stdcall functions are restoring stack by themselves, so, they are called in this way:
push
push
call stdcall_function
2.ccall functions does not restore stack, so, they are called in this way:
push
push
call ccall_function
add esp,number_of_args*4
regards!
===
SpooK - Great! ?:)
you can do this in some ways:
1. do pop same time as push
push a
push b
...
pop ecx (just to restore stack)
pop ecx
2.if you do not need these values in stack you can just correct stack with direct correcting esp:
push a ; (esp=esp-4)
push b ; (esp=esp-4)
...
add esp,8 ; (-> add esp,4*count_of_pushed_dwords)
2a.
mov edi,esp
push a
push b
...
mov esp,edi
now about calling:
1.stdcall functions are restoring stack by themselves, so, they are called in this way:
push
push
call stdcall_function
2.ccall functions does not restore stack, so, they are called in this way:
push
push
call ccall_function
add esp,number_of_args*4
regards!
===
SpooK - Great! ?:)
?????? :)
Thanks for the responses. So to make sure I understand, instead of 3 POP instructions, you can just add 12 to the stack pointer? If the POP instruction increments the stack pointer, doesn't the PUSH instruction decrement the stack pointer automatically assuming that the stack goes from high addresses to low addresses? Thanks.
Yes, the primary purpose of PUSH/POP is to store/load values into memory and then decrement/increment the stack pointer by how much ever was pushed/popped. Consider them both "2-in-1" instructions.
Since you don't really care about retrieving the values after the call, simply adding the amount of data you pushed onto the stack *to* SP/ESP will be the most efficient way of balancing the stack after the call.
Since you don't really care about retrieving the values after the call, simply adding the amount of data you pushed onto the stack *to* SP/ESP will be the most efficient way of balancing the stack after the call.
Yeah, and besides: imagine you've push 70 parameters. Do you fell like popping all of them back? add esp, 280 is better :)
Pleasebear in mind that parameters may be smaller/larger (16-bit, 64-bit, or even zillion-bit :P ). Bur that's another story ;)
Pleasebear in mind that parameters may be smaller/larger (16-bit, 64-bit, or even zillion-bit :P ). Bur that's another story ;)