gpt4 book ai didi

c - 需要弄清楚以下内联汇编代码的含义

转载 作者:太空宇宙 更新时间:2023-11-04 00:39:25 24 4
gpt4 key购买 nike

static int func_name (const uint8_t * address)
{
int result;
asm ("movl $1f, %0; movzbl %1, %0; 1:"
: "=&a" (result) : "m" (*address));

return result;
}

我已经通过 Internet 浏览了内联汇编引用资料。但是我无法弄清楚这段代码在做什么,例如。 $1f 是什么?“m”是什么意思?正常的内联约定不是使用“=r”和“r”吗?

最佳答案

该代码在功能上与 return *address 相同,但不完全等同于此 wrt。到生成的二进制/目标文件。

在 ELF 中,使用前向引用(即 mov $1f, ... 来检索程序集本地标签的地址)导致创建所谓的搬迁。重定位是对链接器的指令(在可执行文件创建时或稍后在可执行文件/库加载时对动态链接器)插入仅在链接/加载时已知的值.在目标代码中,这看起来像:

Disassembly of section .text:0000000000000000 :   0:   b8 00 00 00 00          mov    $0x0,%eax   5:   0f b6 07                movzbl (%rdi),%eax   8:   c3                      retq

请注意此处的值(在 .text 部分的偏移量 1 处)为零,尽管这实际上是不正确的 - 这取决于函数将在运行代码中结束的位置。只有(动态)链接器最终才能知道这一点,而这 block 内存在加载时需要更新的信息实际上是放在目标文件中的:

$ readelf -a xqf.oELF Header:[ ... ]Section Headers:  [Nr] Name              Type             Address           Offset       Size              EntSize          Flags  Link  Info  Align  [ 0]                   NULL             0000000000000000  00000000       0000000000000000  0000000000000000           0     0     0  [ 1] .text             PROGBITS         0000000000000000  00000040       0000000000000009  0000000000000000  AX       0     0     16  [ 2] .rela.text        RELA             0000000000000000  000004e0       0000000000000018  0000000000000018          10     1     8[ ... ]Relocation section '.rela.text' at offset 0x4e0 contains 1 entries:  Offset          Info           Type           Sym. Value    Sym. Name + Addend000000000001  00020000000a R_X86_64_32       0000000000000000 .text + 8[ ... ]

这个 ELF 部分条目说:

  • 查看 .text 部分中的偏移量 1
  • 有一个 32 位值将被零扩展为 64 位 (R_X86_64_32)。这可能旨在用于 32 位代码,但在 64 位非 PIE 可执行文件中,这仍然是将地址放入寄存器的最有效方式;对于 R_X86_64_PC32 RIP 相对重定位,小于 lea 1f(%rip), %0。是的,将 RIP 相关的 LEA 放入 32 位寄存器是合法的,如果您不关心截断地址,则可以节省一个字节的机器代码。
  • 您(作为链接器)需要放置的值是 .text + 8(必须在链接/加载时计算)

这个条目是通过 mov $1f, %0 指令创建的。如果您将其遗漏(或只写 return *address),它就不会出现。

我通过删除 static 限定符强制为上面的代码生成;如果不这样做,一个简单的编译实际上根本不会创建任何代码(static 代码如果不使用就会被删除,而且很多时候如果使用则内联)。

由于该函数是 static 的事实,如前所述,它通常会由编译器在调用站点内联。因此,使用它的信息通常会丢失,调试器检测它的能力也是如此。但是这里显示的技巧可以(间接)恢复它,因为每次使用该函数都会创建一个重定位条目。除此之外,像这样的方法可以用来在二进制文件中建立检测点;在可通过目标文件格式恢复的位置插入众所周知/严格定义但功能上无意义的小型汇编语句,然后让例如调试器/跟踪实用程序在需要时用“更有用”的东西替换它们。

关于c - 需要弄清楚以下内联汇编代码的含义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14922022/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com