News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Memory deletion issue

Started by Ron, July 23, 2015, 12:48:36 AM

Previous topic - Next topic

Ron

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

dedndave

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

dedndave

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

Gunther

Good catch, Dave.  :t It can be adopted with the inline assembler or as an external procedure.

Gunther
You have to know the facts before you can distort them.

Ron

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.

dedndave

        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