This is in a C++ application that calls a function which uses assembly language. The function works correctly but if I execute the delete[] line, it abends.
unsigned char * inB2;
inB2 = new (std::nothrow) unsigned char[count];
if (inB2 != nullptr) {
__asm {
pushad
mov esi, inB
mov edi, inB2
add esi, count
mov ecx, count
xor eax, eax
lodsb
push eax
dec esi
dec esi
L1 :
lodsb
mov[edi], al
dec esi
dec esi
inc edi
dec ecx
jnz L1
pop eax
stosb
//now copy back into inB
//if I comment this out, the function does not abend
mov esi, inB2
mov edi, inB
mov ecx, count
dec ecx
L2:
lodsb
stosb
dec ecx
jnz L2
popad
}
delete[] inB2;
}
I'll admit, C++ is not my strong suit.
RON
that routine makes no sense - lol
you seem to be missing part of the idea behind the string instructions
and - i think the code may attempt to access data beyond the inB and inB2 buffers
by default, the direction flag will be cleared - at least, i believe that to be true
after a LODSB is executed, ESI is automatically incremented (by 1 because it's a byte instruction)
after a STOSB, EDI is automatically incremented in the same manner
LODSW would increment ESI by 2
LODSD would increment ESI by 4
if the direction flag were set, it would decrement the pointers, instead
STD and CLD are very slow instructions on many processors
in fact, LODSB and STOSB aren't as fast as they could be
inside the L2 loop, you use LODSB and STOSB - MOVSB could be used to replace both
the only time you get good performance out of the string instructions is when used with REP
to use REP, you put the count in ECX and execute
the entire L2 loop could be replaced with
rep movsb
but, i believe the trouble is before the loop
carefully step through that code, and keep track of where ESI and EDI are pointing
mov esi, inB
mov edi, inB2
add esi, count
mov ecx, count
xor eax, eax
lodsb
bang !
the first LODSB accesses data beyond the inB buffer
it points to the address of inB, plus the count
so - it is pointing to the first byte that follows the buffer
after LODSB executes, it would point to the next byte after that one :P
Good catch, Dave. :t It can be adopted with the inline assembler or as an external procedure.
Gunther
Thanks. I didn't see that. I'm just trying to (re) learn some string manipulation in assembler. This function takes an unsigned char array and reverses it. Now it works, OK. Including the delete[] at the end.
push esi
push edi
mov ecx,count
mov esi,inB
mov edi,inB2
push esi
push ecx
dec esi
push edi
L1: mov al,[esi+ecx]
mov [edi],al
dec ecx
lea edi,[edi+1]
jnz L1
pop edi
pop ecx
pop esi
rep movsb
pop edi
pop esi