Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
CPU如何知道RAM中的地址是否包含整数、预定义的CPU指令或任何其他类型的数据?_Cpu_Cpu Architecture_Machine Code - Fatal编程技术网

CPU如何知道RAM中的地址是否包含整数、预定义的CPU指令或任何其他类型的数据?

CPU如何知道RAM中的地址是否包含整数、预定义的CPU指令或任何其他类型的数据?,cpu,cpu-architecture,machine-code,Cpu,Cpu Architecture,Machine Code,这让我感到困惑的原因是所有地址都有一个1和0的序列。那么CPU如何区分,比如说,00000100(整数)和00000100(CPU指令)?简称:CPU不知道存储在那里的内容,但指令告诉CPU如何解释它 让我们举一个简单的例子 如果CPU被告知添加存储在位置X的字(比如32位整数),它将获取该地址的内容并将其添加 如果程序计数器到达同一位置,CPU将再次提取该字并将其作为命令执行。这是因为ISA必须考虑什么是有效的指令集以及如何编码数据:内存地址/寄存器/文本 有关ISA如何设计的更多一般信息,请

这让我感到困惑的原因是所有地址都有一个1和0的序列。那么CPU如何区分,比如说,
00000100
(整数)和
00000100
(CPU指令)?

简称:CPU不知道存储在那里的内容,但指令告诉CPU如何解释它

让我们举一个简单的例子

如果CPU被告知添加存储在位置X的字(比如32位整数),它将获取该地址的内容并将其添加


如果程序计数器到达同一位置,CPU将再次提取该字并将其作为命令执行。

这是因为ISA必须考虑什么是有效的指令集以及如何编码数据:内存地址/寄存器/文本

有关ISA如何设计的更多一般信息,请参见此
首先,不同的命令有不同的值(操作码)。这就是CPU知道该做什么的原因

最后,问题依然存在:什么是命令,什么是数据

现代个人电脑使用的是冯·诺依曼(von Neumann)体系结构(),数据和操作码存储在同一存储空间中。(在这两种数据类型之间存在分离的体系结构,如哈佛体系结构)

详细解释所有内容将完全超出stackoverflow的范围,很可能每个帖子的字符数不够

用尽可能少的话回答这个问题(实际上在这个级别上工作的每个人都会因为解释中的捷径而杀了我):

  • 内存中的数据存储在特定地址
  • 每个CPU建议基本上由3个不同的地址组成(不是值-只是地址!):
    • 关于做什么的问题
    • 关于价值的讨论
    • 关于附加值的地址
因此,假设应该执行一个加法,并且内存中有3个可用地址,应用程序将存储(在
5+7
的情况下)(我使用“动词”作为指示)

最后,CPU接收指令
1 2 3
,这意味着
ADD 5 7
(这些东西是顺序敏感的![Command][v1][v2])。。。现在事情变得越来越复杂了

CPU将这些值(实际上不是值,只是值的地址)移动到其寄存器中,然后对其进行处理。要选择的确切寄存器取决于数据类型、数据大小和操作码

在命令
#1#2#3
的情况下,CPU将首先读取这些内存地址,然后知道需要
添加5 7

根据
ADD
的操作码,CPU将知道:

  • 将地址
    #2
    放入r1
  • 将地址
    #3
    放入r2
  • 读取存储在r1中存储的地址处的内存值
  • 读取存储在r2中存储的地址处的内存值
  • 将两个值相加
  • 把结果写在内存的某个地方
  • 将结果放入r3的存储地址
  • 将存储在r3中的地址存储到存储在r1中的内存地址中
注意这是简化的。实际上,CPU需要关于其处理值或地址的确切指令。在汇编中,这是通过使用

  • eax(指存储在寄存器eax中的值)
  • [eax](指存储器中存储在寄存器eax中的地址处的值)
CPU无法对存储在内存中的值执行计算,因此它非常忙于将值从内存移动到寄存器,以及从寄存器移动到内存

i、 如果你有

eax = 0x2
在记忆中

0x2 = 110011
指令呢

MOV ebx, [eax]
这意味着:将当前存储在地址的值(当前存储在
eax
中)移动到寄存器
ebx
中。所以最后

ebx = 110011
(每次CPU进行一次计算时都会发生这种情况!.Memory->Register->Memory)

最后,要求苛刻的应用程序可以读取其预定义的内存地址#2, 产生地址#2568,然后知道计算结果存储在地址#2568。读取该地址将产生值
12
(5+7)

这只是一个很小的例子。有关这方面的详细介绍,请参阅


人们无法真正掌握数据移动的数量,也无法简单地将两个值相加进行计算。做一个CPU所做的事情(在纸上)只需计算“5+7”就需要几分钟,因为没有“5”和“7”-所有内容都隐藏在内存中的地址后面,指向一些位,根据地址0x1处的位指示的内容产生不同的值

简而言之,操作系统告诉它下一条指令在哪里。对于x64,有一个名为rip(指令指针)的特殊寄存器,它保存下一条要执行的指令的地址。它将自动读取该地址的数据,解码并执行该数据,并根据指令的字节数自动递增rip

通常,操作系统可以将内存区域(页面)标记为是否包含可执行代码。如果错误或漏洞试图修改可执行内存,则会发生错误,类似地,如果CPU发现自己试图执行非可执行内存,它也会/应该发出错误信号并终止程序。现在你进入了软件病毒的奇妙世界

CPU(而不是像NX位这样的安全设备)对它是数据还是代码一无所知

数据不会意外地作为代码执行的唯一方法是小心地组织代码,使其永远不会使用用于对代码进行操作的指令引用保存数据的位置

当程序启动时,处理器开始在预定义的位置执行它。
ebx = 110011