I was just checking the disassembly of my C++ program in VS2010. Here it is :
int main()
{
00B613A0 push ebp
00B613A1 mov ebp,esp
00B613A3
These are just artifacts of the disassembler. The ES segment register is already the default segment register used by the STOS instruction, the DS segment register is already the default segment register used for that MOV instruction. Hard to call it a bug but it is certainly unnecessary and inconsistently applied. I reckon that this is triggered by the REP prefix for the STOS instruction and the operand size prefix for that MOV instruction (16 bits instead of 8 or 32). A segment override is also a prefix.
32-bit code uses the flat memory model, the ES, DS, CS and SS segment registers map the entire 4 gigabyte address space. So there is very little reason to need a segment register override. Very different from 16-bit code where the segment registers are important to allow addressing more than 64 KB of memory. You will see segment overrides for the FS register in exception handling code. It points to the Thread Information Block, FS:[0] contains the current SEH frame.
ES is implied as the destination segment for the repeated string operations, but since DS and ES are guaranteed to always be the same on WIN32, it doesn't really matter if the ES override is present (explicit or implied).