2011-09-03 85 views
8

虽然经历了一些内联程序集的C代码,但我遇到了.byte(在开始处有一个Dot)指令。gnu程序集中.byte汇编程序指令的用途是什么?

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

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

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

回答

5

有几个可能性...这里有几个我能想到的把我的头顶部:

  1. 你可以访问它相对于自带.byte指令的标签。例如:

    .byte 0x0a 
    label: 
        mov (label - 1), %eax 
    
  2. 基于该方案的最后链接的布局,也许.byte指令都将作为代码执行。通常你也会在这种情况下有一个标签,虽然...

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

    .byte 0x66 
        mov $12, %eax 
    

    使汇编程序发出你想要的代码。

+1

来自3)的汇编程序急需一个补丁:-) –

+0

'.byte'和['d *'pseudo-ops]有什么区别(http://stackoverflow.com/questions/10168743/x86 - 装配-其中-可变大小使用的-DB-DW-DD)? –

+0

我希望他们是一样的。 –

0

该.byte是一个指令,允许您声明一个只有通过检查才知道的常量字节,而无需任何上下文。

从GNU汇编程序指南:

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

这里的内联汇编的例子:(见compiler asm output and also disassembly of the final binary on the Godbolt compiler explorer

#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; 
} 

您可以mov $1, %%eax 运行结果替换.byte 0xb8, 0x01, 0x00, 0x00, 0x00将是一样的。这表明它可以是一个可以表示一些指令或其他指令的字节。

1

.byte吐出字节无论你在哪里。是否有标签或不指向字节,无所谓。

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

卡尔提到这个问题,但这里是一个完整的例子让它进一步下沉:用nop一个Linux x86_64的实施true抛出:

.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