First, there is no EDS, only DS. Even in 32-bit mode, the segment registers remain 16 bits.
Up vote 0 down vote favorite share g+ share fb share tw.
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 bufferhowmany; 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::bufferecx ;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 } c++ arrays assembly loops link|improve this question edited Dec 19 '09 at 9:24 asked Dec 19 '09 at 7:32kelton52712717 99% accept rate.
The first thing you should do is test it. Then, if it doesn't work and you can't figure out why, come back to us. – paxdiablo Dec 19 '09 at 7:36 There's a better way than looping, check my edited answer.
– Andreas Brinck Dec 19 '09 at 8:46.
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).
As I said I'm pretty new to assembly, and it's hard to find information on assembly with anything newer than 16bit architecture. – kelton52 Dec 19 '09 at 8:31.
The loop instruction requires a target label (it uses relative jumps, and the assembler calculates the difference automatically), so something more like this: char bufferhowmany; memset(buffer,33,howmany); char arr = 0; __asm { MOV eax, buffer ; buffer is a pointer, thus eax contains address MOV eds, eax MOV ecx, howmany ; You probably want the value of howmany, not address buf_loop: MOV arr, eax ; segments are for 16bit DOS code, just dereference the array pointer in INC TYPE buffer ; Move to next element LOOP buf_loop }.
That also fails – kelton52 Dec 19 '09 at 7:52 reguardless though, you can loop to a specific segement offset. – kelton52 Dec 19 '09 at 7:56 I tried to fix up your code as best I can, according to guesses what you're trying to accomplish. It had numerous flaws.
– Daniel Bruce Dec 19 '09 at 8:07.
If so, don't mess with EDS. The loop instruction must give a jump destination label. Loading ebx with ip (or eip) cannot be done as ip is not a proper operand.
My buffer is large so I'm moving to the segment it resides in to do the work. – kelton52 Dec 19 '09 at 7:58 If you are in flat address protected mode, the buffer is in the data segment. Loading EDS is an expensive instruction: don't do it unless absolute necessary.
If the value really needs changing, be sure to set EDS back to what it was before when finished. – wallyk Dec 19 '09 at 8:18.
Label: //some code LOOP label Also if you want to avoid looping, check out the REP MOVS and REP STOS instructions.
I stored the memory location of the beginning of the array...MOV ebx,ip...so it loops back to that and grabs the next character – kelton52 Dec 19 '09 at 7:45 @kelton52 it doesn't work like that, you can't use the value of a register as a label. – Andreas Brinck Dec 19 '09 at 7:50 tried it and it fails the same way. – kelton52 Dec 19 '09 at 7:53 reguardless though, you can loop to a specific segement offset.
– kelton52 Dec 19 '09 at 7:55.
I don't have time to write it out, but using SSE2 registers you can read 16 bytes per loop. You will have to have a byte based loop first to align though (and after).
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.