【问题标题】:Are programming languages and methods inefficient? (assembler and C knowledge needed)编程语言和方法效率低下吗? (需要汇编程序和 C 知识)
【发布时间】:2010-06-16 19:38:11
【问题描述】:

长期以来,我一直在思考和研究汇编形式的C语言编译器的输出,以及CPU架构。我知道这对您来说可能很愚蠢,但在我看来,有些东西非常无效。如果我错了,请不要生气,我看不到所有这些原则是有原因的。如果你告诉我为什么要这样设计,我会很高兴。我真的相信我错了,我知道将 PC 放在一起的人的天才头脑知道这样做的理由。究竟是什么,你问?我马上告诉你,我以 C 为例:

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

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

2:变量分配重复性:

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

【问题讨论】:

  • 为什么投反对票?对我来说,这似乎是一个真正的理论层面的问题。
  • 谢谢,我也是这么写的。
  • @Darel:不是我的反对意见,但问题不是很好。 @b-gen-jack-o-nell,您可能可以用代码片段替换一些措辞并提高清晰度。
  • 好的,没问题,我希望这个问题对其他人尽可能有用。
  • 好吧,凯文已经帮我做了。感谢和抱歉这么多错误,但英语不是我的强项。

标签: c assembly methods


【解决方案1】:

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

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

【讨论】:

  • 好吧,如果目标文件是静态链接的,你可以解决这个问题,因为你知道所有的语法。第二个问题有什么原因吗?
  • 如果每个调用函数 Foo() 的线程都必须为局部变量使用相同的内存地址,这也会使安全多线程变得非常困难。
  • b-gen-jack-o-neill:不容易。我的观点是:你如何将参数传递给函数?我不太明白你的第二个问题。
【解决方案2】:
  1. 因为 C(和大多数其他语言)支持递归,所以函数可以调用自身,并且函数的每次调用都需要任何局部变量的单独副本。此外,在大多数当前处理器上,您的方式实际上会更慢 - 间接寻址非常普遍,处理器已针对它进行了优化。

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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

      由于您正在比较 assembler 和 c(从架构的角度来看它们非常接近),我倾向于说您正在描述微优化,除非您分析代码以查看它是否执行,否则这是没有意义的更好的。

      一般来说,编程语言正在朝着更具声明性的风格发展(即告诉计算机您想要做什么,而不是告诉计算机您希望它如何完成)。当您使用命令式语言(如汇编或 c)进行编程时,您会非常详细地指定您希望如何解决问题。这使编译器几乎没有空间代表您做出优化决策。

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

      【讨论】:

      • 我完全不同意这一点。有很多很多优秀的研究人员在你所说的“微优化”方面做得很好。实际上,我不确定您的意思,因为这个问题直接解决了更有效的编译器输出。我认为关于“声明式编程”的所有这些业务更多是为了迎合一种时尚,而不是在这里吃肉和土豆。大概我们希望有一些方法让所有这些声明性的东西以某种合理的效率执行。顺便说一句,我认为这种声明性的东西比真正需要的要多得多。
      • 对程序进行微优化通常是愚蠢的。对编译器生成的代码进行微优化更有意义,这甚至不是微优化。这些是对已编译代码进行结构更改的建议。
      【解决方案5】:
        1234563 .这是可行的,但是使用当前的硬件非常慢。此外,虚拟内存执行的地址转换也不是免费的,要有效地实现这一点实际上相当复杂。
        解决 ebp(或任何其他寄存器)需要一个多路复用器(选择寄存器)和一个加法器(将偏移量添加到寄存器)。为此花费的时间通常会与其他操作重叠。
      1. 如果您希望能够修改静态值,您必须将其复制到堆栈中。如果你不这样做(说它是 'const'),那么好的 C 编译器不会将它复制到堆栈中。

      【讨论】:

        猜你喜欢
        • 2019-05-01
        • 2012-01-19
        • 1970-01-01
        • 2023-03-06
        • 1970-01-01
        • 2014-10-07
        • 2016-09-27
        • 1970-01-01
        相关资源
        最近更新 更多