【问题标题】:Assembly instruction to dereference a char pointer and return the result用于取消引用 char 指针并返回结果的汇编指令
【发布时间】:2019-09-27 11:51:13
【问题描述】:

我的 CS 书中的一个练习要求一个简短的 (x86-64) 程序集 sn-p 用于将 char 指针作为参数并返回它指向的(第一个)字符的函数。

书中提出的解决方案如下:

movq (%rdi), %rax
movb (%rax), %al

我原以为一条指令就足够了:

movb (%rdi), %al

这两个是等价的吗?我错过了什么?

【问题讨论】:

  • 第一个做两次解引用,就好像你有一个双指针。
  • 这是哪本书,让被同一本书中的相同错误迷惑的未来读者更容易找到这个?
  • 哦,所以这不是char* arg。 :/ 或者它通过引用来获取它,而你忘了提及这一点。不知道如何解决这个误导性问题。也许包括书中的实际措辞,然后答案可以纠正您对它的解释为char*
  • IMO 明显更糟;您的新标题不太具体。搜索和查看问题标题的人不会知道问题的指令序列是什么。并且在问题主体中“除其他外”并没有修改 arg 被称为 char 指针的事实。
  • 我想我们不妨离开它。既然事实证明这不是一本书的错误,那么来源就不那么重要了,我们不妨离开它。有了这个特定的标题和有用的答案,也许它会有一些用处。

标签: assembly x86 x86-64 att


【解决方案1】:

在您的第一个 sn-p 中,发生了两个指针取消引用:

movq (%rdi), %rax
movb (%rax), %al

rdi指向的8字节内存位置被加载到rax中。然后,rax 指向的 1 字节内存位置被加载到al。您可以将其视为完全取消引用指向char的指针的指针(即char **)。

而在您的第二个 sn-p movb (%rdi), %al 中,有一个指针解引用,即 rdi 指向的 1 字节位置被加载到 al 中。您可以将其视为取消引用指向char(即char *)的指针。

【讨论】:

  • 在 x86-64 中加载字节的首选方法是 movzbl (%rax), %eax,将新值写入 RAX,而不是将新的低字节合并到旧 RAX 中。 (特别是如果您正在加载到另一个目标寄存器中,而该目标寄存器还不是该指令的输入依赖项。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-24
  • 2011-07-18
  • 1970-01-01
  • 2013-01-04
  • 2021-12-03
  • 2011-02-04
相关资源
最近更新 更多