编程语言和方法效率低下吗? (需要汇编和C知识)

很长一段时间,我正在思考和研究汇编forms的C语言编译器的输出,以及CPU架构。 我知道这对你来说可能很愚蠢,但在我看来,某些事情是非常无效的。 如果我错了,请不要生气,并且有一些原因我没有看到所有这些原则。 如果你告诉我为什么这样设计,我会很高兴的。 我实际上真的相信我错了,我知道让人们聚在一起的人的天才头脑知道这样做的理由。 究竟是什么,你问? 我马上告诉你,我用C作为例子:

1:堆栈本地范围内存分配:

因此,典型的本地内存分配使用堆栈。 只需将esp复制到ebp,然后通过ebp分配所有内存。 好吧,如果您明确需要默认堆栈RAM,我会理解这一点,但是如果我理解它正确,现代操作系统会使用分页作为应用程序和物理RAM之间的转换层,当您需要的地址在到达实际RAM之前进一步转换字节。 那么为什么不说0x00000000是int a,0x00000004是int b等等? 并通过mov 0x00000000,#10访问它们? 因为您实际上不会访问内存块0x00000000和0x00000004,而是您的操作系统将分页表设置为。 实际上,由于ebp和esp的内存分配使用间接寻址,“my”方式会更快。

2:变量分配的两面性:

运行应用程序时,Loader将其代码加载到RAM中。 当您创建变量或字符串时,编译器会生成在main中创建时将这些值推送到顶部堆栈的代码。 所以有实际的指令,以及内存中的实际数字。 因此,RAM中有2个相同值的条目。 一种是指令forms,第二种是RAM中实际字节的forms。 但为什么? 为什么不只是在声明变量计数到哪个内存块时比使用时,只需插入这个内存位置?

  1. 因为C(和大多数其他语言)支持递归,所以函数可以调用自身,并且函数的每次调用都需要任何局部变量的单独副本。 此外,在大多数当前的处理器上,您的方式实际上会更慢 – 间接寻址非常常见,以至于处理器都针对它进行了优化。

  2. 您似乎希望C(或至少C允许)的行为用于字符串文字。 这有好有坏,例如即使您已经定义了“变量”,也无法实际修改其内容(不会影响指向同一位置的其他变量)。

你将如何实现递归函数? 您所描述的内容相当于在任何地方使用全局变量。

这只是一个问题。 如何链接到预编译的目标文件并确保它不会破坏程序的内存?

您的问题的答案主要包含在不同存储类的不同语义中

  • 谷歌“数据段”
  • 想想全局变量和局部变量之间的行为差​​异。
  • 想想当重复调用函数时,常量变量和非常量变量如何具有不同的要求(或者如Mehrdad所说,递归地)
  • 在多个或递归调用的上下文中再次考虑静态和非静态自动变量之间的区别。

由于您正在比较汇编程序和c(从架构的角度来看它们非常接近),我倾向于说您正在描述微优化,除非您对代码进行分析以查看它是否表现更好,否则这种情况毫无意义。

一般来说,编程语言正朝着更具说明性的方式发展(即告诉计算机你想做什么,而不是你想要它做什么)。 当您使用命令式语言(如程序集或c)进行编程时,您可以非常详细地指定解决问题的方式。 这为编译器提供了代表您做出优化决策的空间。

然而,随着语言变得更具声明性,编译器变得更加智能,因为我们为他们提供了进行更智能性能优化所需的空间。

  1. 如果每个函数都将其第一个变量放在偏移0处,依此类推,则每次输入函数时都必须更改内存映射(如果需要递归,则无法将所有变量分配给唯一地址)。 这是可行的,但对于当前的硬件,它非常慢。 此外,由虚拟存储器执行的地址转换也不是空闲的,实际上非常复杂地实现它。
    寻址具有多路复用器(以选择寄存器)和加法器(将寄存器添加到寄存器)的ebp(或任何其他寄存器)成本。 为此所花费的时间通常可以与其他操作重叠。

  2. 如果您希望能够修改静态值,则必须将其复制到堆栈中。 如果你不这样做(说它是’const’)那么好的C编译器就不会将它复制到堆栈中。