给定序列的一条ASM指令

时间:2019-01-28 20:49:55

标签: assembly x86 nasm

我需要将以下序列作为一条单独的ASM指令编写,但我不知道它是什么指令:

push ebp
mov ebp,esp
mov ebp,[ebp]
mov ebx,[ebp]
mov [esp],ebx

1 个答案:

答案 0 :(得分:4)

不可能使用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个关键的副作用无法重现:< / p>

  • 它不会在EBX中保留[EBP]
  • 如果[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指向没有其他线程引用的回写区域中的可读写存储器,因此优化存储/重载是有效的。但是就像我说的,没有什么可以说我们可以假设的。