15

インラインアセンブリを含むいくつかのCコードを調べているときに、.byte(先頭にドットが付いている)ディレクティブに出くわしました。

Webでアセンブリ参照を確認したところ、メモリに1バイトを予約するために使用されていることがわかりました。

しかし、コードにはステートメントの前にラベルがありませんでした。そのため、ラベルのない.byteディレクティブやその他のデータストレージディレクティブをどのように使用するのか疑問に思いました。

たとえば、コードを記述した場合.byte 0x0a、どのように使用できますか?

4

4 に答える 4

9

いくつかの可能性があります...ここに私が頭のてっぺんから考えることができるカップルがあります:

  1. ディレクティブの後に続くラベルに関連してアクセスできます。.byte例:

      .byte 0x0a
    label:
      mov (label - 1), %eax
    
  2. プログラムの最終的なリンクされたレイアウトに基づいて、.byteディレクティブはコードとして実行される可能性があります。通常、この場合もラベルがありますが...

  3. 一部のアセンブラは、オペランドサイズなどのx86命令プレフィックスの生成をサポートしていません。これらのアセンブラ用に記述されたコードでは、次のようなものがよく見られます。

      .byte 0x66
      mov $12, %eax
    

    アセンブラに必要なコードを出力させるため。

于 2011-09-03T00:20:02.370 に答える
5

実行可能な最小限の例

.byteどこにいてもバイトを吐き出します。ラベルがあるかどうか、バイトを指しているかどうかは関係ありません。

テキストセグメントにいる場合、そのバイトはコードのように実行される可能性があります。

カールはそれについて言及しましたが、これをさらに沈めるための完全な例を次に示します。Linuxx86_64の実装とtrueスロー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

1つのユースケース:新しい手順

ユースケースの1つは、新しい命令がCPU ISAに追加されたが、アセンブラーの非常にエッジのあるバージョンのみがそれをサポートする場合です。

そのため、プロジェクトメンテナは、バイトを直接インライン化して、古いアセンブラでコンパイルできるようにすることを選択できます。

たとえば、類似の.instディレクティブを使用したLinuxカーネルでのこのSpectre回避策を参照してください:https ://github.com/torvalds/linux/blob/94710cac0ef4ee177a63b5227664b38c95bbf703/arch/arm/include/asm/barrier.h#L23

#define CSDB    ".inst  0xe320f014"

Spectreに新しい命令が追加され、カーネルは当面それをハードコーディングすることを決定しました。

于 2015-10-27T06:16:35.767 に答える
4

インラインアセンブリの例を次に示します。

#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これは、ある命令などを表すことができるバイトである可能性があることを示しています。

于 2015-08-21T23:52:05.200 に答える
0

.byteは、コンテキストなしで検査によってのみ認識される定数バイトを宣言できるようにするディレクティブです。

GNUアセンブラガイドから:

.byte  74, 0112, 092, 0x4A, 0X4a, 'J, '\J # All the same value.
于 2011-09-03T00:24:28.167 に答える