I know that call
and ret
will modify the value of esp
and that push
and pop
have a number of variants, but are there other instructions that will affect the stack pointer ?

- 328,167
- 45
- 605
- 847

- 688
- 1
- 7
- 14
-
2The instructions `INT` and `INTO` and `IRET` and many others that control that register directly as with other registers, such as `ADD ESP,8`. – Weather Vane May 23 '17 at 20:20
-
6Search volume 2 of Intel's manual for `ESP ←`? – Michael May 23 '17 at 20:22
-
2Have you tried looking in the manuals? – fuz May 23 '17 at 20:48
-
The manuals are extremely dense and figuring out exactly how to use them to answer a question of that type seems to be out of scope for introduction-level classes (that's the level I'm at). For instance Michael's comment above is helpful on that regard. I believe a "research method" type answer, rather than a list, would be very valuable to me as well as other beginners who might be in the same situation. – iodbh May 23 '17 at 21:09
-
not something we have memorized I would assume we would have to do the same work which is not the point of stackoverflow. The answer is to look at the documentation for the instruction set, how to make that faster or easier is something you have to sort out. – old_timer May 23 '17 at 22:23
-
who knows maybe someone here has that kind of photographic memory with search capabilities... – old_timer May 23 '17 at 22:24
-
3"there is this way of looking for instructions that set a specific register" helps. "RTFM" and "sort it out"are pretty much the opposite of the point of stackoverflow - especially when the manuals in question are > 4500 pages and arguably complex. – iodbh May 23 '17 at 22:42
2 Answers
The following instructions modify the stack pointer as an implicit operand1:
call
enter
int n/into/int 3
iret/iretd
leave
pop
push
ret/retf
sysenter
sysexit
pusha
popa
pushf/pushfd/pushfq
popf/popfd/popfq
vmlaunch/vmresume
eexit
Every instruction that can write an arbitrary general-purpose regiser (like imul reg, r/m32, imm8
or add / sub) can write ESP if you want, but it's only interesting to list one where the stack pointer is an operand even if you don't mention it explicitly. I leave to you the burden of telling primary and side effects apart.
Keep in mind that any instruction capable of generating an exception can potentially modify the stack pointer, at least the kernel stack pointer if not user-space.
I've not considered such instructions in order to avoid trivializing your question.
Those are all the instructions I can find by searching the Intel manuals at the time of creation of this answer.
While I did my best scrutinizing the manuals I wouldn't swear to that list.
1 Either SP
, ESP
or RSP
.

- 40,822
- 8
- 72
- 132

- 41,768
- 5
- 78
- 124
-
Listing `pusha/pushad` like that is odd because `pusha` (at least for NASM and [my insref based on it](https://pushbx.org/ecm/doc/insref.htm#insPUSHA)) can, depending on the code segment's default bitness, mean either `pushaw` or `pushad` (whichever form it is handled as when occurring without `osize` prefix). Your choice of wording appears to default to 16-bit CS where `pusha` means `pushaw`. – ecm Oct 21 '21 at 11:36
-
1@ecm MASM also does that IIRC. I use the mnemonics Intel uses in their manuals. – Margaret Bloom Oct 21 '21 at 14:54
-
Re: the footnote: SP vs. ESP vs. RSP is determined by the stack address size in the SS descriptor, right? I 64-bit is the only option in 64-bit mode, but in protected mode you can have 16-bit address/operand size as the default with a 32-bit stack-address size, I think. (I guess that's getting a bit off topic for this question.) – Peter Cordes Oct 21 '21 at 23:18
The push(a/ad/f)
and pop(a/ad/f)
instruction groups are modifying the stack pointer (e)sp
. Interrupt calls int
also modify it. The instruction call
will push the return address to the stack and ret
removes it. In the form of ret NUMBER
additionally that number of bytes are removed from the stack to clean it.
Of course you can use (e)sp
in other instructions, like mov
or arithmetic instructions like add
or sub
. It will be represented in the REG, R/M, or BASE fields in the opcode-byte, modR/M-byte, and/or sib-byte.

- 33,889
- 7
- 43
- 76

- 371
- 1
- 4
-
5`ENTER`, `LEAVE` are modifying stack pointer too, but it's not exactly "side effect", more like the "main effect". – Ped7g May 23 '17 at 21:19
-
1@Ped7g: I think the point is having [ER]SP as an *implicit* operand, whether it's the main effect or not. ESP is one of the 8 general-purpose registers, so every instruction that can write a GPR can modify it, including weird examples like `imul esp, edx, 1` to set ESP = EDX in a convoluted way. – Peter Cordes Oct 21 '21 at 22:30
-
@PeterCordes: I once wrote some code that used SP as a scribble register. Clearly interrupts must be disabled to do that. – Joshua Oct 21 '21 at 22:57