assembly - 给定序列的一条 ASM 指令
问题描述
我需要将以下序列编写为一条 ASM 指令,但我不知道它是什么指令:
push ebp
mov ebp,esp
mov ebp,[ebp]
mov ebx,[ebp]
mov [esp],ebx
解决方案
用 1 条甚至 2 条指令完全重现所有输入值的所有行为是不可能的。
前 3 条指令压入 EBP,然后将刚刚保存的 EBP 值重新加载到 EBP。所以前 3 个的净效应是lea esp, [esp-4]
(不是 SUB,因为那会影响 FLAGS)1。
push ebp ; save old EBP, ESP-=4
mov ebp,esp
mov ebp,[ebp] ; reload old EBP
;; net effects so far: ESP-=4.
;; memory at [ESP] replaced with old-EBP.
mov ebx,[ebp] ; EBX = [EBP]. This could overlap with dword [ESP]
mov [esp],ebx ; replace pushed original_EBP value with [original_EBP]
我怀疑他们回答他们正在寻找的可能是push [ebp]
,但如果是这样,这个问题完全是垃圾。 有 2 个不会重现的关键副作用:
- 它不会
[EBP]
在 EBX 中留下价值 - 如果
[EBP]
(部分)重叠[ESP-4]
要重现 set-EBX 行为,您至少需要 2 条指令。x86 有一些复杂的指令,但没有一个会推送内存并复制到整数寄存器。 Jester 的 2 条指令序列看起来最接近:mov ebx, [ebp]
/push ebx
。
您也可以考虑push dword [ebp]
/ mov ebx, [esp]
,但这显然效率较低,并且存储/重新加载[ebp]
与给定序列不同的值。
[ebp]
但是,如果与推送目的地重叠,它们都不会重现确切的行为。例如lea ebp, [esp-2]
,在这些说明之前考虑。 给定的序列在加载之前存储了 EBP [ebp]
,没有任何东西告诉我们没有重叠。 如果您使用 EBP 作为帧指针,通常它不会指向 ESP 下方,但我们没有被告知。
脚注 1: 当然,假设没有其他线程正在修改我们存储/重新加载 EBP 的内存,否则存储/重新加载可能不会总是重新加载相同的值!我们最终会存储到[esp]
,因此如果 ESP 指向不可读写的内存,优化掉一些内存访问并不会改变故障行为。
问题中没有任何内容表明我可以对 ESP 指向的位置做出任何假设,或者与该内存位置异步发生的其他事情。
就我们所知,ESP 指向一个 MMIO 区域,每次存储/加载都有一个可见的副作用,比如将位放在并行端口的引脚上,或者读取它们!
在正常情况下,ESP 指向写回区域中没有其他线程引用的可读写内存,那么优化存储/重新加载是有效的。但就像我说的,没有什么说我们可以假设。
推荐阅读
- ios - 快速绘制带有笔画动画的复选标记
- asp.net-mvc-5 - 无法访问此站点 Asp.net MVC 5
- javascript - 在 Asp.Net core Odata 中,如何防止过滤器字符串替换传递的文本
- r - 在 r 中加载数据时无法重命名 WDI 指标列?
- ruby-on-rails - 如何将新参与者添加到邮箱中的现有对话中?
- javascript - Prisma - 无法创建自定义解析器
- multidimensional-array - 使用 CUDA 的显式 FDM
- php - 如何在php中发送消息,刷新页面后,消息在php中消失?
- python - 使用嵌套 k 折交叉验证的 keras 中的超参数调整
- javascript - 每次执行函数时如何使随机数组项相同