Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Smaller instruction than "add esp, 4"

Me again.

I'm having a lot of "add esp, 4" in my program and I'm trying to reduce its size. Is there any smaller instruction that can replace "add esp, 4" ?

like image 594
DavidH Avatar asked Jan 10 '10 20:01

DavidH


People also ask

Does RET increase ESP?

The RET instruction causes in effect, a POP into EIP in other words whatever is at [ESP] is given to EIP (the instruction pointer) and then ESP is increased by 4 bytes. Note how after the call, ESP is restored to equilibrium.

Does push decrement ESP?

ESP (the stack pointer) is decremented by push since the x86 stack grows down — i.e. the stack grows from high addresses to lower addresses.

What is ESP 4?

4 in 4(%esp) refers to offset that is added to %esp before it is dereferenced.

What is push to ESP?

push ebp preserves ESP, the previous stack frame pointer, this is so it can be returned to at the end of the function. A stack frame is used to store local variables and each function will have its own stack frame in memory.


4 Answers

pop edx  

Or any other integer register you don't mind destroying.

This is what modern compilers actually do (clang and sometimes gcc) because it's often optimal for performance as well as code-size on modern CPUs.

An add esp,4 after a call would force the CPU's stack engine to insert a stack-sync uop before doing the actual add. If you otherwise don't modify use ESP directly except with stack instructions (e.g. as part of an addressing mode) before the next push/pop/call/ret, then you saved a uop by using pop.

That cache line of stack memory is going to be hot in cache (making the load cheap) if any other stack instructions ran recently.

like image 98
jspcal Avatar answered Oct 17 '22 01:10

jspcal


A better question might be: "why do you have so many add esp, 4 instructions, and what can you do to have less of them?" It's somewhat unusual to be doing lots of small increments to the stack pointer like this.

Are you moving things to/from the stack at the same time? Could you use push/pop instead?

Alternatively, do you really need to update the stack pointer so frequently, or could you get away with moving it once at the beginning of a block of code to make some space on the stack, then restoring it once at the end of the routine?

What are you really trying to do?

like image 22
Stephen Canon Avatar answered Oct 17 '22 01:10

Stephen Canon


Sorry if this will sound trivial... but if you manage to reorder your code so that several add esp, 4 instructions are consecutive, you can of course simplify them to e.g.:

add esp, 8

or even:

add esp, 12

Just make sure that moved instructions don't reference esp or the stack; or if they do reference something on the stack, they do only via the ebp register.

like image 4
stakx - no longer contributing Avatar answered Oct 17 '22 00:10

stakx - no longer contributing


One way to do it if you have multiple function calls:

sub esp, 4
mov 0(esp), param
call ...
...
mov 0(esp), param2
call ...
...
add esp, 4

That is, reuse the stack allocated for the first parameter over several function calls.

like image 2
Richard Pennington Avatar answered Oct 17 '22 00:10

Richard Pennington