1

以下の 2 つの組み立て説明書の目的を理解していただけますか? (詳細については、最後にアセンブリ + C コードを参照してください)。ありがとう !

movzx  edx,BYTE PTR [edx+0xa]
mov    BYTE PTR [eax+0xa],dl

===================================

以下のアセンブリコード:

push   ebp    
mov    ebp,esp
and    esp,0xfffffff0
sub    esp,0x70
mov    eax,gs:0x14
mov    DWORD PTR [esp+0x6c],eax
xor    eax,eax
mov    edx,0x8048520
lea    eax,[esp+0x8]
mov    ecx,DWORD PTR [edx]
mov    DWORD PTR [eax],ecx
mov    ecx,DWORD PTR [edx+0x4]
mov    DWORD PTR [eax+0x4],ecx
movzx  ecx,WORD PTR [edx+0x8]
mov    WORD PTR [eax+0x8],cx
movzx  edx,BYTE PTR [edx+0xa]    ; instruction 1
mov    BYTE PTR [eax+0xa],dl     ; instruction 2
mov    edx,DWORD PTR [esp+0x6c]
xor    edx,DWORD PTR gs:0x14
je     804844d <main+0x49>
call   8048320 <__stack_chk_fail@plt>
leave  
ret

===================================

以下の C ソース コード (ライブラリのインクルードなし):

int main() {
    char str_a[100];    
    strcpy(str_a, "eeeeefffff");
}
4

1 に答える 1

5

strcpy() 呼び出しをインライン化すると、コード ジェネレーターは 11 バイトをコピーする必要があることを認識できます。文字列リテラル "eeeeefffff" には 10 文字があり、ゼロ ターミネータが 1 つ余分に含まれています。

コード オプティマイザは、コピー ループを 4 回に展開し、4 + 4 + 2 + 1 バイト移動しました。3 バイトを移動するプロセッサ命令がないため、このようにする必要があります。あなたが求めている命令は、11 番目のバイトをコピーします。movzx を使用するのは少しやり過ぎですが、おそらく DL レジスタをロードするよりも高速です。

文字列を変更すると、生成されたコードの変化を観察します。余分な文字を追加すると、4 + 4 + 4 の 3 つの移動に展開する必要があります。文字列が長くなりすぎると、memmove のようなものにフォールバックするはずです。

于 2013-08-18T17:46:18.690 に答える