ほとんどのプロセッサは、さまざまなタイプのデータを操作するためのさまざまな命令を提供するため、通常、タイプ情報は生成されたマシンコードに「組み込まれ」ます。追加のタイプメタデータを保存する必要はありません。
いくつかの具体的な例が役立つかもしれません。以下のマシンコードは、SuSE Linux Enterprise Server(SLES)10を実行しているx86_64システムでgcc 4.1.2を使用して生成されました。
次のソースコードを想定します。
int main( void )
{
int x, y, z;
x = 1;
y = 2;
z = x + y;
return 0;
}
上記のソース(を使用gcc -S
)に対応する生成されたアセンブリコードの中身を、コメントを追加します:
main:
.LFB2:
pushq %rbp ;; save the current frame pointer value
.LCFI0:
movq %rsp, %rbp ;; make the current stack pointer value the new frame pointer value
.LCFI1:
movl $1, -12(%rbp) ;; x = 1
movl $2, -8(%rbp) ;; y = 2
movl -8(%rbp), %eax ;; copy the value of y to the eax register
addl -12(%rbp), %eax ;; add the value of x to the eax register
movl %eax, -4(%rbp) ;; copy the value in eax to z
movl $0, %eax ;; eax gets the return value of the function
leave ;; exit and restore the stack
ret
あとに続くものがいくつかありますret
が、それは議論には関係ありません。
%eax
32ビットの汎用データレジスタです。 %rsp
は、スタックポインタを保存するために予約されている64ビットのレジスタで、スタックに最後にプッシュされたもののアドレスが含まれています。 %rbp
は、現在のスタックフレームのアドレスを含むフレームポインターを保存するために予約されている64ビットのレジスタです。スタックフレームは、関数を入力するとスタック上に作成され、関数の引数とローカル変数用のスペースを確保します。引数と変数には、フレームポインターからのオフセットを使用してアクセスします。この場合、変数のメモリはに格納されているアドレスの「下」に12バイトです。 x
%rbp
上記のコードでは、32ビットワードをある場所から別の場所にコピーするために使用される命令を使用してx
、(1に格納された-12(%rbp)
)整数値をレジスタにコピーします。我々は、呼の整数値を付加する、(に格納されているが、既にの値に)。私たちはその結果に保存しています、。 %eax
movl
addl
y
-8(%rbp)
%eax
-4(%rbp)
z
double
値を変更するので、値ではなく値を処理しint
ます。
int main( void )
{
double x, y, z;
x = 1;
y = 2;
z = x + y;
return 0;
}
gcc -S
再度実行すると、次のことがわかります。
main:
.LFB2:
pushq %rbp
.LCFI0:
movq %rsp, %rbp
.LCFI1:
movabsq $4607182418800017408, %rax ;; copy literal 64-bit floating-point representation of 1.00 to rax
movq %rax, -24(%rbp) ;; save rax to x
movabsq $4611686018427387904, %rax ;; copy literal 64-bit floating-point representation of 2.00 to rax
movq %rax, -16(%rbp) ;; save rax to y
movsd -24(%rbp), %xmm0 ;; copy value of x to xmm0 register
addsd -16(%rbp), %xmm0 ;; add value of y to xmm0 register
movsd %xmm0, -8(%rbp) ;; save result to z
movl $0, %eax ;; eax gets return value of function
leave ;; exit and restore the stack
ret
いくつかの違い。movl
andの代わりにand addl
を使用movsd
しますaddsd
(倍精度浮動小数点数を割り当てて追加します)。中間値を保存する代わりに%eax
、を使用します%xmm0
。
これは、型がマシンコードに「焼き付けられた」と言うときの意味です。コンパイラは、特定のタイプを処理するための適切なマシンコードを生成するだけです。