【问题标题】:Strings from a machine language perspective从机器语言的角度来看字符串
【发布时间】:2016-05-20 20:48:04
【问题描述】:

从低级汇编和体系结构的角度来看,指令中的字符串与数字的处理方式有何不同?我试图从在线课程中了解编译器是如何工作的,但最终不太了解一个字长为 64 位的体系结构如何理解和关联包含一个字符串但不适合的 Unicode 的多个字符一条指令。基于在字符串末尾寻找空字节的体系结构,字符串是否具有完全独立的指令?我相信,理解这一点会使编译器更容易理解。谢谢!

【问题讨论】:

  • 它们只是数组。与数字数组没有根本区别。 Unicode 代码点只是一个数字。一种编程语言使它看起来更容易,创造了一个字符串是它自己的对象的错觉。
  • 从机器语言的角度来看,它们也只是数字。
  • “字符串末尾的空字节”:是一种特定的数据结构模式,仅由某些语言和库使用。我怀疑它的用途正在扩大。另一种模式是计数代码单元。 (所有文本都有编码,例如UTF-16。)这两种模式都有很长的历史。

标签: string assembly architecture compilation


【解决方案1】:

低级机器指令语言有一些字符串指令(如 CMPS、MOVS 等)。这些指令,以及 REP、REPNZ 等前缀都基于用户先验知道字符串的长度,因此这些指令有效地在每个字节/字/双字/四字上重复执行相同的指令。这些指令比手动编码的循环更快,仅仅是因为这些指令还触发了内存的预读。

这些不假定任何 NULL 终止条件或其他一些终止条件。这些也完全不了解被视为字符串的数据是 Unicode 还是 ASCII 或任何此类特定格式。这些都是特定于语言的约定。

有许多编程技术可以快速确定字符串的长度,只要它使用相同的指令集由已知标记(NULL,或“句号”)终止。

因此,总而言之,低级架构侧重于自动化顺序存储数据处理过程的重复性,但不会以任何其他方式将字符串与数字“区别”对待。

相信这会有所帮助。

【讨论】:

  • 强调 CPU 不知道文本,这些指令尽管在描述中包含“字符串”,但只是比较或移动连续数据。它们可能被称为移动块,移动阵列,......
  • 是的,x86 "rep string" 指令主要用于显式长度的字符串(如 std::string,它存储长度),而不是隐式长度(0 终止)的字符串。如果没有rep 前缀,它们可以在任何一种字符串的循环中正常工作。 x86 字符串指令分散了人们对字符串是 char 的数组具有隐式或显式长度这一事实的注意力。无需讨论它们,但不需要讨论 memset / memcpy 的 asm 实现的其他选项。
  • 还要注意repe cmps 不是写memcmp 的最快方式(SSE2 pcmpeqb 更快)。 rep stosrep movs 很快,但与手写循环相比,其他的并没有那么特别。特别是repe scasb (memchr) 很糟糕,因为您不能使用更宽的元素大小,而且微码实现不会在内部使用 16B 负载来加速它。指令表见agner.org/optimizex86 tag wiki
  • 无论如何,x86 的字符串指令在其他架构上没有等效项。像 ARM 这样的 RISC CPU 必须通过正常循环实现 memcpymemchr。嗯,在仔细阅读了这个问题之后,我明白了这个答案的意义,但是由于“字符串”指令实际上并不是编译器处理字符串的方式,所以我认为这不是最好的答案。
猜你喜欢
  • 2016-01-01
  • 2010-12-23
  • 2013-01-24
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
  • 2012-11-01
  • 1970-01-01
相关资源
最近更新 更多