gnu程序集中.byte汇编程序指令的用途是什么?

vja*_*n27 14 assembly gnu-assembler inline-assembly

在浏览一些具有内联汇编的C代码时,我遇到了.byte(开头有一个Dot)指令.

在检查Web上的程序集引用时,我发现它用于在内存中保留一个字节.

但是在代码中,声明之前没有标签.所以我想知道什么是未标记的.byte指令或任何其他数据存储指令的用途.

例如,如果我编码.byte 0x0a,我该如何使用它?

Car*_*rum 9

有几种可能性......这里有一对我可以想到的最爱:

  1. 您可以相对于指令后面的标签访问它.byte.例:

      .byte 0x0a
    label:
      mov (label - 1), %eax
    
    Run Code Online (Sandbox Code Playgroud)
  2. 根据程序的最终链接布局,.byte指令可能会作为代码执行.通常你也会在这种情况下有一个标签,但......

  3. 一些汇编程序不支持为操作数大小等生成x86指令前缀.在为这些汇编程序编写的代码中,您经常会看到如下内容:

      .byte 0x66
      mov $12, %eax
    
    Run Code Online (Sandbox Code Playgroud)

    使汇编程序发出您想要的代码.

  • 来自3)的汇编程序需要补丁,紧急:-) (2认同)

Cir*_*四事件 5

最小的可运行示例

.byte无论您身在何处,都会吐出字节。是否有标签指向字节,并不重要。

如果您碰巧在文本段中,那么该字节可能会像代码一样运行。

Carl 提到了它,但这里有一个完整的例子让它更深入:一个 Linux x86_64 实现truewith a nopthrow in:

.global _start
_start:
    mov $60, %rax
    nop
    mov $0, %rdi
    syscall
Run Code Online (Sandbox Code Playgroud)

产生与以下完全相同的可执行文件:

.global _start
_start:
    mov $60, %rax
    .byte 0x90
    mov $0, %rdi
    syscall
Run Code Online (Sandbox Code Playgroud)

因为nop被编码为字节0x90

一个用例:新指令

一种用例是将新指令添加到 CPU ISA,但只有非常边缘版本的汇编器会支持它。

因此,项目维护者可以选择直接内联字节以使其可在较旧的汇编器上编译。

例如,使用类似.inst指令在 Linux 内核上查看此 Spectre 解决方法:https : //github.com/torvalds/linux/blob/94710cac0ef4ee177a63b5227664b38c95bbf703/arch/arm/include/asm/barrier.h#L23

#define CSDB    ".inst  0xe320f014"
Run Code Online (Sandbox Code Playgroud)

为 Spectre 添加了一条新指令,内核决定暂时对其进行硬编码。