汇编中变量的旧值在哪里?

Posted

技术标签:

【中文标题】汇编中变量的旧值在哪里?【英文标题】:where does the old value of the variable in assembly go? 【发布时间】:2021-12-17 04:31:21 【问题描述】:

我有一个问题,我一直在到处寻找答案,但我找不到,我的问题是在更改变量值时使用汇编语言,旧变量的值在哪里? 例如/

mov ax,'3'

如果我们将'3' 更改为'a' '3' 会去哪里??

【问题讨论】:

变量的旧值会丢失。 它也不是真正特定于汇编的,在大多数编程语言中,赋值自然会覆盖丢失的旧值。 白墙用蓝笔刷完后好像白消失了一样被覆盖 假设我举起四根手指。然后我放下它们,举起七个手指。四号去哪儿了?这基本上是同一个问题,同样毫无意义。 CPU 寄存器中的晶体管处于代表一个值的状态。现在它们处于不同的状态,代表不同的值。除非您明确将其复制到其他地方,否则任何地方都不存在前状态的记录。 【参考方案1】:

您的问题实际上相当深入,因此我将概述一些涉及您问题的主题。

高级语言使用变量——变量具有名称、类型、范围、值,并且许多具有动态生命周期:它们被创建和销毁,例如通过函数调用、构建数据结构等......

与机器码相比,变量是一个逻辑概念。

在机器代码中,我们有由 CPU 寄存器和内存组成的物理存储。该存储在程序的整个生命周期内都存在(模虚拟内存)。 (事实上​​,物理存储在计算机的整个生命周期都存在;它就在那里。)

汇编程序员和编译器的一项重要工作是将我们算法的逻辑变量映射到处理器的物理存储中。

我们经常重新利用物理存储,从逻辑上释放旧映射并启动新映射。我们在汇编中通过简单地在某处写入一个值来做到这一点,而不告诉处理器任何进一步的细节。物理存储的约定是存储最后写入的值,以便在随后读取时返回。寄存器通常被重新利用,因为它们在互连一系列机器代码操作时很有用。

处理器从不读取数据或变量声明(或逻辑变量到物理存储的映射),因此在机器代码中,每次使用物理存储时,我们都会告诉处理器如何处理其中保存的数据。

有时,逻辑变量的生命周期结束(因此映射完成),例如,函数返回(因此它的输入参数和局部变量被破坏)但变量映射到的物理存储不会立即重用/由程序重新调整用途——在这种情况下,该变量的最后一个值仍然存在于该存储位置。

这告诉我们,尽管如此,在汇编中很容易出现逻辑错误,例如未初始化的变量,这些变量似乎具有随机或垃圾值(但它们并不是真正随机的,因为重新利用物理存储,如果没有完全替换/完全初始化,物理存储将记​​住它被告知要记住的最后一件事,可能来自不同逻辑变量到同一存储的较早映射)。现代语言进行分析以防止未初始化的变量和某些其他类型的逻辑错误(例如类型检查),但这些错误检查(大部分)不会发生在汇编中,因此这种正确性是程序员的责任。

物理存储是通过电子电路完成的。电路中的反馈回路允许记住一个位(二进制数字,1 或 0)直到改变。 (将输出连接回存储电路的输入会创建该反馈回路。)在内部,各个存储位可以:清零、设置为 1、读取以显示他们被告知要存储的最后一个值。位分组允许存储更大的数字,例如ax,它是将 16 个存储位组合在一起。

为了存储新值,旧值被遗忘——存储二进制数字的门根据需要充电或放电,以存储新值。因此,一些旧值(作为费用)被重复使用(例如,如果新值的某个位恰好与先前值中的那个位相同),并且如果您愿意,一些旧值会变成耗散的电能,通常作为热量,例如或许如果前一个位值的 1 被更改为 0,则该 1 被释放。


总之,变量是我们的伪代码和高级编程语言的一个逻辑概念。它们按照我们的算法来来去去。物理存储始终存在,经常被重新利用(通过机器代码程序)用于我们算法的不同逻辑变量。硬件使用电路中的反馈回路存储位,并根据机器代码程序的指令对物理存储位进行充电和放电以保持新值,而旧值可能会作为能量损失逃逸。

下次当您感到笔记本电脑发热时,想想所有那些旧值都在逃逸!

【讨论】:

以上是关于汇编中变量的旧值在哪里?的主要内容,如果未能解决你的问题,请参考以下文章

swift 遗忘的旧汇编

汇编 学到哪里写哪里——这只是一个开始

c++中定义的变量名称到底存在哪里了?

汇编 - 如何在汇编中将一个常数乘/除以另一个常数?

Java HotSpot中内在方法的汇编实现代码在哪里?

汇编语言如何读取一个地址中存储的变量