我再次。
我的程序中有很多“添加esp,4”,我正在尝试减小它的大小。是否有任何较小的指令可以取代“add esp,4”?
答案 0 :(得分:5)
pop edx
或者你不介意破坏的任何其他整数寄存器。
This is what modern compilers actually do(clang,有时是gcc),因为它通常是性能以及现代CPU上代码大小的最佳选择。
add esp,4
之后的call
会强制CPU的堆栈引擎在执行实际add
之前插入堆栈同步uop。如果您在下一次push / pop / call / ret之前没有直接修改使用ESP,除了堆栈指令(例如作为寻址模式的一部分),那么您使用pop
保存了一个uop。
如果最近运行了任何其他堆栈指令,堆栈内存的缓存行将在缓存中变得很热(使负载变得便宜)。
答案 1 :(得分:5)
一个更好的问题可能是:“为什么你有这么多add esp, 4
指令,你能做些什么来减少它们?”像这样对堆栈指针进行大量的小增量有点不寻常。
您是否同时向堆叠移动堆栈?您可以使用push
/ pop
吗?
或者,你真的需要如此频繁地更新堆栈指针,或者你可以在代码块的开头移动它一次以在堆栈上创建一些空间,然后在结束时恢复它一次例程?
你真的想做什么?
答案 2 :(得分:4)
很抱歉,如果这听起来微不足道......但是如果您设法重新排序代码以便连续使用多个add esp, 4
指令,那么您当然可以将它们简化为例如:
add esp, 8
甚至:
add esp, 12
确保移动的指令不引用esp
或堆栈;或者如果他们确实在堆栈上引用某些内容,则只能通过ebp
寄存器进行。
答案 3 :(得分:2)
尝试使用pop eax
答案 4 :(得分:2)
如果您有多个函数调用,可以使用一种方法:
sub esp, 4
mov 0(esp), param
call ...
...
mov 0(esp), param2
call ...
...
add esp, 4
即,在多个函数调用中重用为第一个参数分配的堆栈。
答案 5 :(得分:1)
如果您在调用后调整堆栈,则更好的方法是使用RETN X
,其中X
是要在ESP
上添加的字节数...
PUSH EAX
CALL EBX (in this func, you use RETN 4)
<<here the stack is already aligned>>
或者,使用POPFD =x
答案 6 :(得分:0)
如果您正在管理堆栈(我假设您是),您可以使用push eax
和pop eax
向堆栈添加值并维护esp
。您还可以使用pusha/popa
等指令将所有GPR打开/弹出堆栈,并pushf/popf
将EFLAGS寄存器推入/弹出堆栈。
答案 7 :(得分:0)
popfd
只会在一个字节中向esp
添加4,副作用是随机化您的标记。执行起来可能很慢;我不知道。
当然,查看代码或了解真正的要求会有所帮助。