我想知道是否有可能(如果是,如何编写)与push
具有相同效果的指令序列。例如,如果ax
的内容是1200,并且我做了push ax
,那么可以使用其他什么指令来完成push ax
所做的操作?执行与推动相同的操作的指令序列
回答
一些其他答案使用[sp]
进行堆栈寻址,但在16位模式下以及在32位或64位模式下都不可行。但是,在32位模式下,您可以使用[esp]
,而在x86-64中,可以使用[rsp]
进行内存寻址,但在16位模式下,不存在使用sp
的内存寻址。有关16位模式下可能的存储器寻址模式,请参见here。
所以,你需要做的:存储bp
某处的值,复制sp
为bp
,然后用bp
解决堆栈,并最终恢复bp
原始值。
如果你有一个地方来存储bp
,很简单(这是YASM/NASM语法):
mov [bp_storage], bp
sub sp,2
mov bp,sp
mov [bp],ax
mov bp,[bp_storage]
...
bp_storage dw 0
使用寄存器而不是内存地址一样bp_storage
这里是微不足道了。
编辑:增加的版本不修改标志(下面),因为push
也不修改标志。
上面的代码修改标志,而push ax
不修改任何标志。这可以通过存储第一ah
到存储器中,然后加载标志为ah
与lahf
,然后从ah
存储所述标志,以存储器,然后修改如上堆叠,然后事后通过使用sahf
从存储器经由ah
恢复标志并最终恢复来解决ah
从内存中。
编辑:为了模拟push ax
没有标志的变化,ah
必须lahf
之前被保存,mov [bp],ax
之前加载。固定。
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
修改AF
,CF
,OF
,PF
,SF
,ZF
,而lahf
负载和sahf
仅存储AF
,CF
,PF
,SF
,ZF
(无OF
)。但是,sp
不应该在正常的堆栈使用情况下溢出。
但是,如果你不能访问内存,并且想用栈来存储bp
你可以这样做,但是如果你没有使用自由寄存器,事情会变得复杂。但是,如果你使用的是实模式的操作系统,你可以阻止中断与cli
,交换bp
和sp
,使用bp
堆栈再次处理,交换bp
和sp
,并再次允许中断与sti
。
编辑:sp
的值需要减去2以模拟push ax
。固定。该版本不修改标志(中断标志除外)。
cli
xchg bp,sp
lea bp,[bp-2]
mov [bp],ax
xchg bp,sp
sti
至少如果没有记错,这大致相当于:
sub sp, 2
mov [sp], ax
减去等于从SP写入所需的数据的大小的值,然后移动/写堆栈上你想要的对象。编译器一直在做这类事情。以-S输出为例。谨防原子/线程的问题,如果你这样做......
*哪些*原子/线程问题?我认为你在发明它们。 – 2013-02-14 18:15:44
在嵌入式系统上,您以非原子方式使用堆栈指针,并且事情变得繁荣。 “移动堆栈指针”,中断,推送信息,返回,“写入信息”,繁荣。 – 2013-02-14 18:30:49
顺便说一句,我已upvoted其他答案,因为他们包括实际的示例代码,而我懒惰,没有:) – 2013-02-14 18:31:55
如果我没有忘记Intel语法:
lea sp, [sp-2]
mov [sp], ax
我用lea
避免触及FLAGS
(既不push
也不mov
或lea
触摸它们,但sub
和dec
)。
编辑:事实证明,我忘记了更重要的事情:没有[sp]
寻址模式。正确答案是@nrz的答案,我可以应用于80386及以上版本的esp
和eax
(将为lea esp,[esp-4]
)。
'mov [sp],ax'无效。 x86中没有这样的指令。 'esp'和'rsp'可以用于内存寻址,'sp'不能。看到我的答案。 – nrz 2013-02-14 18:40:58
- 1. unix命令执行与设置操作相当的列表比较
- 2. ActionScript - 两个不同指令的相同操作码?
- 3. 对相同的选项菜单项执行不同的操作
- 4. 线程同步执行操作顺序
- 5. 无论承诺履行如何执行相同的操作?
- 6. 动作与动作指令中的avm指令
- 7. 如何将此curl命令转换为执行相同操作的Python代码?
- 8. 操作的列具有相同的值
- 9. 装配错误:“指令操作数必须是相同大小”
- 10. 防止多个用户执行相同的操作
- 11. 对多个功能输入执行相同的操作
- 12. 如何处理onClick执行相同操作的许多按钮?
- 13. 使用相同的参考对SQL结果执行操作
- 14. 专注于一个JTextField并执行与其相关的操作
- 15. 为什么我的DbProviderFactory与SqlClientFactory执行的操作不同?
- 16. jquery如何淡入工作?对animate()执行相同操作()
- 17. C:我如何使用与我的运行程序相同的命令行参数来执行()我的程序
- 18. 指令没有执行到正确的顺序与nodejs
- 19. 相同的指令与不同的消息 - angularJS
- 20. 执行表与BigQuery的命令列表
- 21. 如果元素的类与点击元素的ID相同,请执行下列操作
- 22. 该segue没有执行推动动作
- 23. 多个@Pattern的行为与OR操作相同
- 24. 从不同的ViewModel执行相同的Prism命令
- 25. 执行相同的takePicture动作的多个按钮Swift
- 26. 执行操作
- 27. 执行操作
- 28. 如何匹配字符串(一行)相同的模式,并执行相同的操作再次
- 29. 列表操作与序言
- 30. 选择与另一列ID相同,但不同值的行和列指定值
没有投票给你,但一个简单的dec不会覆盖上面写的大小。你需要一个减法或类似的东西。 – 2013-02-14 18:08:53
现在比较好,但'ax'是一个词,所以'dec sp'两次 – 2013-02-14 18:08:54
@AntonKovalenko:好点。谢谢。 – 2013-02-14 18:09:18