繁体   English   中英

.byte 汇编指令在 gnu 汇编中有什么用?

[英]What is the use of .byte assembler directive in gnu assembly?

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

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

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

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

有几种可能性......这里有几个我能想到的:

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

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

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

     .byte 0x66 mov $12, %eax

    使汇编器发出您想要的代码。

最小的可运行示例

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

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

Carl 提到了它,但这里有一个完整的例子来让它进一步深入:一个true的 Linux x86_64 实现,并抛出一个nop

.global _start
_start:
    mov $60, %rax
    nop
    mov $0, %rdi
    syscall

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

.global _start
_start:
    mov $60, %rax
    .byte 0x90
    mov $0, %rdi
    syscall

因为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"

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

这是内联汇编的示例:

#include <stdio.h>
void main() {
   int dst;
   // .byte 0xb8 0x01 0x00 0x00 0x00 = mov $1, %%eax
   asm (".byte 0xb8, 0x01, 0x00, 0x00, 0x00\n\t"
    "mov %%eax, %0"
    : "=r" (dst)
    : : "eax"  // tell the compiler we clobber eax
   );
   printf ("dst value : %d\n", dst);
return;
}

(请参阅编译器 asm 输出以及 Godbolt 编译器资源管理器上最终二进制文件的反汇编。)

您可以将.byte 0xb8, 0x01, 0x00, 0x00, 0x00替换为mov $1, %%eax运行结果将相同。 这表明它可以是一个字节,可以代表一些指令例如移动或其他。

.byte 是一个指令,允许您声明一个常量字节,仅通过检查而没有任何上下文。

来自 GNU 汇编器指南:

.byte  74, 0112, 092, 0x4A, 0X4a, 'J, '\J # All the same value.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM