Ok here’s my problem. I want to loop through a simple char buffer using
inline asm and VC++;
My agenda is to create a loop that reads information from memory as fast as physically possible
heres my code
char buffer[howmany];
memset(buffer,33,howmany);
char arr = 0;
__asm
{
MOV eax,seg buffer ;operand size conflict
MOV eds,eax
MOV ecx,[howmany]
MOV ebx,ip
MOV arr, ES::buffer[ecx] ;operand size conflict
;inline assembler syntax error in 'third operand'
;found 'bad token'
LOOP ebx ;inline assembler syntax error in 'opcode'; found 'bad token'
; 'LOOP' : identifier is reserved word
}
I’m pretty new with assembly, but this seems right, but it doesn’t work? I’m not sure why. Thanks in advance.
Final Solution
__asm
{
LEA esi, buffer
MOV ecx,howmany
buf_loop:
mov eax, [esi]
inc esi
dec ecx
jnz buf_loop
}
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:
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:
For a modern CPU, it’s usually better to use more, but simpler, instructions.
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:
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).