问题标签 [opcode]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
3694 浏览

php - PHP 操作码缓存/Zend 加速和 include_once 与 require_once

我有一位同事正在研究我们基于 PHP 的应用程序的操作码缓存/Zend 加速(我一直认为这些是同一件事)。他的基准测试似乎表明,如果我们将(大型)类库包含在 require_once 中,我们并没有看到性能优势,但我们确实看到了使用 include_once 时的性能优势。

这对我们俩来说都很腥,但我没有时间亲自检查我们的基准方法,我的同事比我更能容忍鱼的气味。:)

有没有人遇到过这样的事情?如果没有,对可能通过从 include_once 切换到 require_once 导致性能提高的其他事情有什么想法?

0 投票
4 回答
1349 浏览

c++ - 从 vc++ 调用存储在堆中的代码

想象一下我正在做这样的事情:

如何定义一个函数指针来调用 p ,就好像它是一个函数一样?(我正在使用 VC++ 2008 express)。

谢谢

0 投票
3 回答
7103 浏览

assembly - 有人可以解释这个直接组装的 x86 JMP 操作码吗?

在学校,我们一直在使用引导程序来运行没有操作系统的独立程序。我一直在研究这个程序,当启用保护模式时,通过直接将操作码和操作数组装为程序中的数据来执行远跳转。这是给 GNU 汇编器的:

首先,为什么要这样做(而不是指令助记符)?

我一直在查看英特尔手册,但仍然对代码感到有些困惑。特别是在第 2A 卷第 3-549 页中,有一个操作码表。相关条目:

实际的操作码很明显,但第一个字节 0x66 让我感到困惑。参考英特尔手册中的表格, cp 显然意味着后面会跟着一个 6 字节的操作数。接下来的两行显然是 6 个字节。0x66 编码一个“操作数大小覆盖前缀”。这和表中的cp有什么关系?我原以为cp会有一些十六进制值,但是有这个覆盖前缀。有人可以帮我解决这个问题吗?

这是来自 od 的转储:

TARGET_ADDRESS 被定义为 0x00010000。

我也对最后两个字节的重要性感到困惑。然而,这似乎完全是另一个问题。现在已经很晚了,我已经盯着代码和英特尔手册看了好几个小时,所以我希望我能明白我的意思。

感谢您的关注!

0 投票
2 回答
14911 浏览

opcode - 未处理的侏儒表达式

谁能告诉我以下分段错误到底是什么意思?

它在solaris 10 i386上。

任何建议表示赞赏。

0 投票
2 回答
1040 浏览

c# - 使用 C# 将 PHP 脚本转换为 OpCode 的最简单方法是什么?

使用 C# 将 PHP 脚本(.php)转换为 OpCode/Bytecode(操作码)的最简单方法是什么?如果必须,我可以使用 DLL。

我需要为我正在工作的项目完成此操作,以便更轻松地分析 PHP 代码。

欢迎任何想法或想法。

0 投票
1 回答
383 浏览

ruby - RubyVM 中的 putspecialobject 操作码是如何工作的?

我正在研究 RubyVM 的实现,并且我到处搜索有关操作码的一些文档,但无济于事。

如果有人具体知道putspecialobject操作码是如何工作的,或者只是一个指向一些完整文档的链接,我将不胜感激!

0 投票
2 回答
837 浏览

c# - 这些操作码是做什么用的?

使用反射器我得到以下输出:

为了

第 11-14 行是做什么的?我调用一个函数并得到一个结果(第 7 行)。我将结果转换为正确的返回类型(c 行) - 为什么不立即返回?

不知何故,转换后的结果被存储为一个局部变量——然后无条件跳转到下一行,再次加载局部变量。为什么?

在我看来,第 11-14 行和局部变量可以省略...?

0 投票
4 回答
3422 浏览

performance - VM 设计:更多操作码还是更少操作码?什么是更好的?

不要感到震惊。这是很多文字,但恐怕如果不提供一些详细信息,我将无法真正展示这一切的全部内容(并且可能会得到很多并不能真正解决我的问题的答案)。这绝对不是一项任务(正如某人在他的评论中荒谬地声称的那样)。

先决条件

由于这个问题可能根本无法回答,除非至少设置了一些先决条件,所以这里是先决条件:

  • 应解释虚拟机代码。不禁止可能存在 JIT 编译器,但设计应针对解释器。
  • VM 应该是基于寄存器的,而不是基于堆栈的。
  • 答案可能既不假设有一组固定的寄存器,也不假设它们的数量是无限的,两者都可能是这种情况。

此外,我们需要更好地定义“更好”。有几个属性必须考虑:

  1. VM 代码在磁盘上的存储空间。当然,您总是可以在这里放弃所有优化并仅压缩代码,但这对(2)有负面影响。
  2. 解码速度。如果将代码转换为可以直接执行的东西需要太长时间,那么存储代码的最佳方式是无用的。
  3. 内存中的存储空间。此代码必须在有或没有进一步解码的情况下直接可执行,但如果涉及进一步解码,则在执行期间和每次执行指令时完成此编码(在加载代码时仅完成一次解码计入第 2 项)。
  4. 代码的执行速度(考虑到常见的解释器技术)。
  5. VM 的复杂性以及为其编写解释器的难度。
  6. VM 自身需要的资源量。(如果 VM 运行的代码大小为 2 KB 并且执行速度比眨眼快,这不是一个好的设计,但是它需要 150 MB 来执行此操作,并且它的启动时间远高于代码的运行时间它执行)

现在举例说明我实际上所说的或多或少的操作码。看起来实际上设置了操作码的数量,因为每次操作需要一个操作码。然而它并不那么容易。

同一操作的多个操作码

您可以进行类似的操作

将 R1 和 R2 的值相加,将结果写入 R3。现在考虑以下特殊情况:

这些是您可以在许多应用程序中找到的常见操作。您可以使用已经存在的操作码来表达它们(除非您需要不同的操作码,因为最后一个操作码具有 int 值而不是寄存器)。但是,您也可以为这些创建特殊的操作码:

和之前一样。优势在哪里?ADD2 只需要两个参数,而不是 3,INC 甚至只需要一个。因此,这可以在磁盘和/或内存中进行更紧凑的编码。由于将任何一种形式转换为另一种形式也很容易,因此解码步骤可以在两种方式之间转换以表达这些陈述。不过,我不确定这两种形式会在多大程度上影响执行速度。

将两个操作码组合成一个

现在让我们假设您有一个 ADD_RRR(R 代表寄存器)和一个 LOAD 来将数据加载到寄存器中。

您可以拥有这两个操作码并始终在整个代码中使用这样的结构......或者您可以将它们组合成一个新的操作码,名为 ADD_RMR(M 代表内存)

数据类型与操作码

假设您有 16 位整数和 32 位整数作为本机类型。寄存器是 32 位的,因此任何一种数据类型都适合。现在,当您添加两个寄存器时,您可以将数据类型设为参数:

例如,有符号和无符号整数也是如此。这样 ADD 可以是一个短操作码,一个字节,然后你有另一个字节(或者可能只是 4 位)告诉 VM 如何解释寄存器(它们是 16 位还是 32 位值)。或者您可以废弃类型编码,而使用两个操作码:

有人可能会说两者完全相同 - 只需将第一种方式解释为 16 位操作码即可。是的,但是一个非常天真的解释器可能看起来完全不同。例如,如果每个操作码有一个函数并使用 switch 语句进行调度(不是最好的方法,函数调用开销,switch 语句也可能不是最优的,我知道),两个操作码可能如下所示:

每个功能都以某种添加为中心。第二个可能看起来像这样:

将子交换机添加到主交换机或将子调度表添加到主调度表。当然,无论类型是否显式,解释器都可以做任何一种方式,但根据操作码设计,任何一种方式都会让开发人员感觉更原生。

元操作码

由于没有更好的名字,我会这样称呼他们。这些操作码本身没有任何意义,它们只是改变了后面的操作码的含义。就像著名的 WIDE 运算符:

例如,在第二种情况下,寄存器是 16 位的(因此您可以添加更多),在第一种情况下只有 8 个。或者,您不能有这样的元操作码,并且有一个 ADD 和一个 ADD_WIDE 操作码。像 WIDE 这样的元操作码避免使用 SUB_WIDE、MUL_WIDE 等,因为您始终可以在所有其他正常操作码之前添加 WIDE(始终只有一个操作码)。缺点是单独的操作码变得毫无意义,您必须始终检查它之前的操作码是否是元操作码。此外,VM 必须为每个线程存储一个额外的状态(例如,我们现在是否处于宽模式)并在下一条指令之后再次删除该状态。甚至 CPU 也有这样的操作码(例如 x86 LOCK 操作码)。

如何找到一个好的权衡???

当然,您拥有的操作码越多,开关/调度表就会变得越大,在磁盘或内存中表达这些代码所需的位数就越多(尽管您可以更有效地将它们存储在数据不存在的磁盘上必须由 VM 直接执行);此外,VM 将变得更加复杂,代码行数也更多——另一方面,操作码越强大:您越来越接近每个表达式,即使是复杂的表达式,都将在一个操作码中结束的地步。

选择小的操作码可以很容易地对 VM 进行编码,并且我猜会导致非常紧凑的操作码 - 另一方面,这意味着您可能需要大量的操作码来执行简单的任务,并且每个不经常使用的表达式都必须成为某种(本机)函数调用,因为它不能使用任何操作码。

我在 Internet 上阅读了很多关于各种 VM 的信息,但没有任何消息来源能够真正做出良好且公平的权衡。设计 VM 就像设计 CPU,有些 CPU 的操作码很少,它们速度很快,但您也需要很多这样的 CPU。并且有许多操作码的 CPU,有些非常慢,但你需要更少的操作码来表达相同的代码。看起来“越多越好”的CPU完全赢得了消费市场,而“越少越好”的CPU只能在服务器市场或超级计算机业务的某些部分生存。虚拟机呢?

0 投票
3 回答
1588 浏览

php - 带变量的 APC 缓存包括

我一直在用 PHP 对 APC 缓存进行一些研究,发现条件包含不起作用。喜欢:

我的问题是:我可以通过变量包含来解决这个问题吗?如:

后面的代码会被 APC 成功缓存吗?

0 投票
7 回答
1054 浏览

c - C字符串文字不在机器代码中?

我需要稍微更改 exe 中的字符串,我不再有源代码。它是用 C 写的。

我注意到 C 字符串文字似乎根本没有出现在机器代码列表中——无论如何都没有出现在原始 ASCII 中,也没有出现在 utf8/16/32 或类似的东西中。它们似乎是编码的,我猜是 32 位操作码的一部分。例如,我知道代码有 c 行: print("My string"); 通过字节 'm' 'y' ' ' 's' 等,但字符串似乎根本没有出现,甚至在任何 utf8/16/32 编码中都没有,甚至在 1/2/3/4/5 中也没有/6/7/8 每个字符之间的字节(我已经检查了所有这些组合)。

据我了解,文字可能是立即操作码,并且这些可能在非字节对齐位置具有 8 位 ASCII 值。有人知道我应该寻找什么操作码吗?目前,即使我一点一点地移动整个文件,我仍然找不到任何看起来像字符串的东西。