【问题标题】:Does pushing a register empty that register?推送一个寄存器会清空那个寄存器吗?
【发布时间】:2019-12-24 20:25:07
【问题描述】:

我已经阅读了很多有关这方面的书籍和说明,但从未指定的一件事是,在将寄存器压入堆栈后会发生什么。例如,如果您在汇编中写入“push ECX”,ECX 寄存器的内容将被压入堆栈(显然)。我不知道的是,一旦你这样做了,ECX 寄存器是保留它在推送之前包含的值,还是在推送之后它自己清空?

【问题讨论】:

    标签: x86 stack nasm


    【解决方案1】:

    CPU 几乎总是 copy,而不是 copy + zero-the-src。尽管像 mov 这样的指令助记符表示“移动”,但实际操作是“复制”(在寄存器之间),或者从内存加载或存储。

    寄存器不能是“空的”,它总是有一些价值。 (除了传统的 x87 FP 堆栈寄存器;有一个单独的状态寄存器可以跟踪哪些 x87 寄存器为空/有值)。

    如果指令破坏了它的源操作数,文档中总是会注明。就像在高级编程语言中,读取变量不会修改它,除非发生了非常奇怪的事情。


    您可以通过使用push 和2 个不同的寄存器值轻松尝试并自己找到答案。在您的调试器中单步执行它,并注意寄存器值没有改变(只有 ESP 和内存发生了变化)。

    您还可以查看 ISA 参考手册(HTML 摘录),https://www.felixcloutier.com/x86/push.Z E Nir ​​引用了其中的“操作”部分。

    【讨论】:

      【解决方案2】:

      寄存器在push指令后保持其值。

      push 影响两个地方:获取新值的堆栈内存,以及现在指向新顶部的esp 的值。 你可以从push操作的描述中推断:

      if(StackAddressSize == 32) {
          if(OperandSize == 32) {
              ESP = ESP - 4;
              SS:ESP = Source //push doubleword
          }
          else { //OperandSize == 16
              ESP = ESP - 2;
              SS:ESP = Source; //push word
          }
      }
      else { //StackAddressSize == 16
          if(OperandSize == 16) {
              SP = SP - 2;
              SS:ESP = Source //push word
          }
          else { //OperandSize == 32
              SP = SP - 4;
              SS:ESP = Source; //push doubleword
          }
      }
      

      来源:https://c9x.me/x86/html/file_module_x86_id_269.html

      https://c9x.me/x86/ 是 x86 指令的绝佳袖珍参考,随意使用!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-05
        • 1970-01-01
        • 2016-08-26
        • 2020-07-24
        • 2021-04-09
        • 1970-01-01
        相关资源
        最近更新 更多