Some other answers use [sp] to address the stack, but this is not possible in 16-bit mode, as well as in 32-bit or 64-bit modes. However, in 32-bit mode you can use [esp] , and in x86-64 you can use [rsp] to address memory, but in 16-bit mode address memory is not used sp . See here for possible memory addressing modes in 16-bit mode.
So what you need to do: save the bp value somewhere, copy sp to bp , then use bp to address the stack and finally restore the original bp value.
If you have bp storage space, this is easy (this is in the YASM / NASM syntax):
mov [bp_storage], bp sub sp,2 mov bp,sp mov [bp],ax mov bp,[bp_storage] ... bp_storage dw 0
Using a register instead of a memory address such as bp_storage is also trivial here.
Edit: A version has been added that does not change flags (below), since push also does not change flags.
The code above changes flags, while push ax does not change any flags. This can be solved by storing the first ah in memory, and then loading the flags in ah using lahf , then storing the flags from ah into memory, then changing the stack as described above, and then restoring the flags from memory through ah using sahf and finally , recover ah from memory.
Edit: To simulate push ax without changing flags, ah must be saved to lahf and loaded to mov [bp],ax . Fixed.
mov [ah_storage],ah lahf mov [flags_storage],ah mov [bp_storage],bp sub sp,2 mov bp,sp mov ah,[ah_storage] mov [bp],ax mov bp,[bp_storage] mov ah,[flags_storage] sahf mov ah,[ah_storage] ... bp_storage dw 0 ah_storage db 0 flags_storage db 0
sub modifies AF , CF , OF , PF , SF , ZF , and lahf loads and sahf stores only AF , CF , PF , SF , ZF (no OF ). However, sp should never overflow with normal stack usage.
But if you cannot access memory and want to use the stack to store bp , you can do it, but if you don't have free registers, things get more complicated. But if you use a real mode OS, you can block interrupts with cli , exchange bp and sp , use bp to address the stack, exchange bp and sp again and enable interrupts again with sti .
Edit: The sp value must be subtracted by 2 to simulate push ax . Fixed. This version does not change flags (except interrupt flag).
cli xchg bp,sp lea bp,[bp-2] mov [bp],ax xchg bp,sp sti