1

VS2010でC++プログラムの逆アセンブリをチェックしていました。ここにあります :

int main()
{
00B613A0  push        ebp  
00B613A1  mov         ebp,esp  
00B613A3  sub         esp,0D4h  
00B613A9  push        ebx  
00B613AA  push        esi  
00B613AB  push        edi  
00B613AC  lea         edi,[ebp-0D4h]  
00B613B2  mov         ecx,35h  
00B613B7  mov         eax,0CCCCCCCCh  
00B613BC  rep stos    dword ptr es:[edi]  
00B613BE  mov         eax,dword ptr [___security_cookie (0B67000h)]  
00B613C3  xor         eax,ebp  
00B613C5  mov         dword ptr [ebp-4],eax  
    char temp[] = "hello";
00B613C8  mov         eax,dword ptr [string "hello" (0B6573Ch)]  
00B613CD  mov         dword ptr [ebp-10h],eax  
00B613D0  mov         cx,word ptr ds:[0B65740h]  
00B613D7  mov         word ptr [ebp-0Ch],cx  

    return 0;
00B613DB  xor         eax,eax  
}

問題の行は次のとおりです。

00B613BC  rep stos    dword ptr es:[edi]  

00B613D0  mov         cx,word ptr ds:[0B65740h] 

なぜ彼らが使っているdword ptr es:[edi]のかわかりませんword ptr ds:[0B65740h]。dword ptrの意味は知っていますが、最後に追加された部分がわかりませ:es:ds。私はこの構文を何度も見て、見過ごされてしまいました。

ありがとう、

Devjeet

4

2 に答える 2

6

これらは逆アセンブラの単なるアーティファクトです。ESセグメントレジスタはすでにSTOS命令で使用されるデフォルトのセグメントレジスタであり、DSセグメントレジスタはすでにそのMOV命令で使用されるデフォルトのセグメントレジスタです。それをバグと呼ぶのは難しいですが、それは確かに不必要であり、一貫して適用されていません。これは、STOS命令のREPプレフィックスとそのMOV命令のオペランドサイズプレフィックス(8または32ではなく16ビット)によってトリガーされると思います。セグメントオーバーライドもプレフィックスです。

32ビットコードはフラットメモリモデルを使用し、ES、DS、CS、およびSSセグメントレジスタは4ギガバイトのアドレス空間全体をマップします。したがって、セグメントレジスタのオーバーライドが必要になる理由はほとんどありません。セグメントレジスタが64KBを超えるメモリのアドレス指定を可能にするために重要である16ビットコードとは大きく異なります。例外処理コードにFSレジスタのセグメントオーバーライドが表示されます。これはスレッド情報ブロックを指し、FS:[0]には現在のSEHフレームが含まれています。

于 2011-11-29T04:41:22.567 に答える
1

ESは、繰り返される文字列操作の宛先セグメントとして暗黙的に示されますが、DSとESはWIN32で常に同じであることが保証されているため、ESオーバーライドが存在するかどうか(明示的または暗黙的)は実際には問題ではありません。

于 2011-11-29T02:05:21.453 に答える