做同样的事情推指令序列 [英] Instruction sequence that does the same thing as push
问题描述
我想知道是否有可能(如果有,如何)写的指令序列,将有作为推
同样的效果。例如,如果斧
的内容是1200,我做了推AX
,我可以用什么其他指令完成什么推AX
呢?
I would like to know if it is possible (and if so, how) to write a sequence of instructions that would have the same effect as push
. For example, if the contents of ax
is 1200 , and I do a push ax
, what other instructions can I use to accomplish what push ax
does?
推荐答案
一些其他的答案使用 [SP]
堆栈处理,但它不能在16位模式,也不能在32位或64位模式要么。然而,在32位模式下可以使用 [ESP]
和X86-64可以使用 [RSP]
对于内存寻址,但在16位模式没有内存寻址使用 SP
。请参见这里在16位模式下可能的内存寻址模式。
Some other answers use [sp]
for stack addressing, but it is not possible in 16-bit mode, nor in 32-bit or 64-bit modes either. However, in 32-bit mode you can use [esp]
and in x86-64 you can use [rsp]
for memory addressing, but in 16-bit mode there is no memory addressing that uses sp
. See here for possible memory addressing modes in 16-bit mode.
所以,你需要做的:存储 BP
某处,复制 SP
到<$ c的值$ C> BP ,然后用 BP
解决堆栈,并最终恢复原值 BP
。
So, what you need to do: store the value of bp
somewhere, copy sp
into bp
, then use bp
for addressing the stack, and finally restore the original value of bp
.
如果您有 BP
的地方存放,这很容易(这是YASM / NASM语法):
If you have a place where to store bp
, that's easy (this is in YASM/NASM syntax):
mov [bp_storage], bp
sub sp,2
mov bp,sp
mov [bp],ax
mov bp,[bp_storage]
...
bp_storage dw 0
使用寄存器而不是内存地址,比如 bp_storage
这里是微不足道了。
编辑:补充说明不修改标志(如下图)版本,为推
不要么修改标志
Added version that does not modify flags (below), as push
doesn't modify flags either.
上面的code修改标志,而推AX
不修改任何标志。这可以通过存储第一啊
到内存中,然后装入标志为啊
与 LAHF解决
,然后存储从标志啊
内存,然后修改堆栈的上面,然后事后通过啊
SAHF 终于从内存中恢复啊
>。
The code above modifies flags, whereas push ax
does not modify any flags. That can be solved by storing first ah
into memory, then loading flags into ah
with lahf
, then storing the flags from ah
to memory, then modifying the stack as above, and then afterwards restoring flags from memory via ah
by using sahf
and finally restoring ah
from memory.
编辑::要模拟推AX
无标志的变化,啊
必须是前 MOV [BP],AX
保存在 LAHF
和加载。固定的。
To simulate push ax
without changes in flags, ah
must be saved before lahf
and loaded before 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
分
修改 AF
, CF
,的
, PF
, SF
, ZF
,而<一HREF =http://web.itu.edu.tr/kesgin/mul06/intel/instr/lahf.html相对=nofollow> LAHF
载荷和 SAHF
只存储 AF
, CF
, PF
, SF
, ZF
(没有的
)。然而, SP
应该永远不会溢出在正常使用堆栈。
sub
modifies AF
, CF
, OF
, PF
, SF
, ZF
, whereas lahf
loads and sahf
stores only AF
, CF
, PF
, SF
, ZF
(no OF
). However, sp
should never overflow in normal stack usage.
但是,如果你不能访问内存,并且希望使用堆栈来存储 BP
你可以做到这一点,但如果你既没有免费注册使用,事情变得复杂。但是,如果你使用的是实模式的操作系统,可以阻止与 CLI
中断,交换 BP
和 SP
,使用 BP
堆栈处理,交换 BP
和 SP
一次允许再次与 STI
。
But, if you can't access memory, and want to use stack to store bp
you can do that, but if you neither have free registers to use, things get complicated. But if you are using a real mode OS, you can block interrupts with cli
, exchange bp
and sp
, use bp
for stack addressing, exchange bp
and sp
again and allow interrupts again with sti
.
编辑:的值 SP
需要2到减去模拟推AX
。固定。此版本不修改标志(除中断标志)。
the value of sp
needs to subtracted by 2 to simulate push ax
. Fixed. This version does not modify flags (except interrupt flag).
cli
xchg bp,sp
lea bp,[bp-2]
mov [bp],ax
xchg bp,sp
sti
这篇关于做同样的事情推指令序列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!