First, there is no EDS, only DS. Even in 32-bit mode, the segment registers remain 16 bits.
Second, unless you're working on an ancient system like a DOS extender, or something really unusual (a lot different from a typical desktop/server OS like Windows, Linux, OS/X, BSD, etc.) you shouldn't modify any segment registers in any case. Most current systems use a "flat" memory model, where the OS sets up all1 the segment registers with a base of 0 and a limit of the top of memory, so you never have any reason to modify any of them at all.
Unfortunately, while it's easy to say your code is wrong, it's a bit harder to say what would be right -- you haven't said enough about what you want to do. Right now, it looks like you're copying from a buffer, but each time through the loop you're overwriting the value you wrote in the last iteration, so you might as well just copy the last word and be done. For looping through the buffer to accomplish much, you'd want to copy it to a destination buffer of the same (or larger) size:
mov ecx, howmany
mov esi, offset FLAT:source
mov edi, offset FLAT:dest
rep movsd
As others have already pointed out, the operand for a loop instruction is a label, not a register. What they don't seem to have pointed out is that with modern CPUs (anything newer than the original Pentium) you usually want to avoid using the LOOP instruction at all. Just for the sake of argument, however, a loop to do the move like above would look like:
mov ecx, howmany
mov esi, offset FLAT:source
mov edi, offset FLAT:dest
move_loop:
lodsd
stosd
loop move_loop
For a modern CPU, it's usually better to use more, but simpler, instructions.
; same setup as above
move_loop:
mov eax, [esi]
mov [edi], eax
inc esi
inc edi
dec ecx
jnz move_loop
The other side of things is that in this case, it's unlikely to matter -- unless it all fits in cache, a block move like this will almost always be limited by the memory bandwidth -- moves don't get much faster, but to get the last little bit of improvement, you want to use SSE instructions/registers.
Edit: One last detail. VC++ (among others) won't let you define a label inside an _asm block, so if you need a label, you do something like:
_asm {
mov ecx, howmany
mov esi, offset FLAT:source
mov edi, offset FLAT:dest
}
move_loop:
_asm {
lodsd
stosd
loop move_loop
}
1Well, not all -- FS and possibly GS won't be this way, but CS, DS, ES and SS will be. You don't want to change any of them anyway (in fact, attempting to do so will normally just get your program shut down).