我刚刚在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
答案 0 :(得分:5)
这些只是反汇编程序的工件。 ES段寄存器已经是STOS指令使用的默认段寄存器,DS段寄存器已经是用于该MOV指令的默认段寄存器。很难把它称为一个错误,但它肯定是不必要的和不一致的应用。我估计这是由STOS指令的REP前缀和该MOV指令的操作数大小前缀(16位而不是8或32)触发的。段覆盖也是前缀。
32位代码使用平面存储器模型,ES,DS,CS和SS段寄存器映射整个4千兆字节的地址空间。因此,几乎没有理由需要段寄存器覆盖。与16位代码非常不同,其中段寄存器对于允许寻址超过64 KB的内存很重要。您将在异常处理代码中看到FS寄存器的段覆盖。它指向线程信息块,FS:[0]包含当前的SEH帧。
答案 1 :(得分:1)
ES隐含为重复字符串操作的目标段,但由于DS和ES保证在WIN32上始终相同,因此ES覆盖是否存在(显式或隐含)并不重要。< / p>