Меньшая инструкция, чем "добавить esp, 4" - PullRequest
5 голосов
/ 10 января 2010

Я снова.

В моей программе много "add esp, 4", и я пытаюсь уменьшить его размер. Есть ли меньшая инструкция, которая может заменить «добавить esp, 4»?

Ответы [ 8 ]

5 голосов
/ 10 января 2010

Лучший вопрос может быть: «Почему у вас так много add esp, 4 инструкций, и что вы можете сделать, чтобы их было меньше?» Несколько необычно делать много маленьких приращений к указателю стека, как это.

Вы перемещаете вещи в / из стека одновременно? Не могли бы вы использовать push / pop вместо?

В качестве альтернативы, вам действительно нужно обновлять указатель стека так часто, или вы можете с легкостью перемещать его один раз в начале блока кода, чтобы освободить место в стеке, а затем восстановить его один раз в конце рутина?

Что вы действительно пытаетесь сделать?

5 голосов
/ 10 января 2010
pop edx  

Или любой другой целочисленный регистр, который вы не против уничтожить.

Это то, что современные компиляторы на самом деле делают (clang и иногда gcc), потому что это часто оптимально как для производительности, так и для размера кода на современных процессорах.

add esp,4 после call заставит механизм стека ЦП вставить синхронизацию стека перед выполнением фактического add. Если в противном случае вы не измените использование ESP напрямую, за исключением инструкций стека (например, как часть режима адресации) перед следующим push / pop / call / ret, то вы сохранили моп, используя pop.

Эта строка кэша стековой памяти будет горячей в кэше (что делает загрузку дешевой), если какие-либо другие инструкции стека выполнялись недавно.

4 голосов
/ 10 января 2010

Извините, если это будет звучать тривиально ... но если вам удастся изменить порядок кода таким образом, чтобы несколько add esp, 4 инструкций были последовательными, вы, конечно, можете упростить их, например ::

add esp, 8

или даже:

add esp, 12

Просто убедитесь, что перемещенные инструкции не ссылаются на esp или стек; или если они ссылаются на что-либо в стеке, они делают это только через регистр ebp.

2 голосов
/ 10 января 2010

Один из способов сделать это, если у вас несколько вызовов функций:

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

То есть повторно использовать стек, выделенный для первого параметра, через несколько вызовов функций.

2 голосов
/ 10 января 2010

Попробуйте использовать pop eax

1 голос
/ 21 января 2011

Если вы выравниваете стек после вызова, лучший способ сделать это - использовать RETN X, где X - это количество байтов, добавляемых в ESP ...

PUSH EAX
CALL EBX (in this func, you use RETN 4)    
<<here the stack is already aligned>>

Или используйте POPFD =x

0 голосов
/ 12 января 2010

popfd добавит 4 к esp всего за один байт, с побочным эффектом рандомизации ваших флагов. Это может быть медленным, чтобы выполнить; Я не знаю.

Конечно, это поможет увидеть код или узнать, что ваши требования действительно .

0 голосов
/ 10 января 2010

Если вы управляете стеком (я так полагаю), вы можете использовать push eax и pop eax, чтобы добавить значения в стек и поддерживать esp. Вы также можете использовать такие инструкции, как pusha/popa для включения / выключения всех GPR-ов в стек / из стека и pushf/popf для включения / выключения регистров EFLAGS в / из стека.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...