0

I have an assignment which a user enters a string (below 101 char) and the machine removes all non-letter elements (numbers, symbols etc.) using the ASCII character table, this is what i have so far. I don't know how to remove an element from an array, any help? Thank you!

push esi
call option5

remNum:
mov al, byte ptr [edx + esi]

cmp al, 41h
ja ongoing
cmp al, 5Ah
jb ongoing

cmp al, 61h
ja ongoing
cmp al, 7Ah
jb ongoing

mov al, 20h
mov byte ptr [edx+esi], al

ongoing:
inc esi

Loop remNum

pop esi
call option5
call waitmsg
ret
option3 ENDP
Amidana
  • 1
  • 3
  • "Removing" an array element means copying all later elements over to fill the gap. It can't be done in constant time; that's one downside of arrays as a data structure. The normal way to do this is to keep separate read and write pointers which start equal, but the write pointer doesn't advance when you skip a char. (you could special-case the start and not actually load / store back to the same place until you find the first letter to skip. But that's optional). – Peter Cordes Oct 28 '19 at 05:45
  • It should be pretty close to constant if your array size is within reason. Wouldn't it just be a memcpy of all elements after the removal to the index of the removal and then decrementing size by one? Without even accounting for further optimizations that should scale fairly well. As long as the vector remains in a contiguous physical memory block, otherwise you'll have to deal with additional MMU time. I'm sure the STL has other optimizations as well like ``sts::remove_if`` building an iterator to reconstruct the array in a single shot. – Pickle Rick Oct 28 '19 at 05:58
  • @PickleRick: Yes, removing 1 element costs a memmove of the rest of the array. Thus it costs O(n/2) = O(n) time, not O(1) like a linked-list or tree deletion. But fortunately you can do an arbitrary number of deletions in one O(n) compaction pass. Of course then you're checking single bytes at a time, going vastly slower than memcpy speed. (Unless you can use SIMD left-packing [AVX2 what is the most efficient way to pack left based on a mask?](//stackoverflow.com/q/36932240) to process 4 or 8 elements at once. Or 16 by expanding to dword for AVX512 vpcompressd) – Peter Cordes Oct 28 '19 at 06:14
  • @PickleRick: Or like some kind of data structure where each element has a bit that lets you mark it as deleted. Anything other than a flat array offloads some of the cost onto readers, of course. And yes, memmove left by a byte left can be faster than memcpy into a separate destination, if it wasn't hot in L1d cache to start with. Writing to cold memory typically requires an RFO of the cache line before the store can commit, but if you're writing just behind where you're reading the cache line is hopefully already exclusively owned by this core. – Peter Cordes Oct 28 '19 at 06:16
  • @PickleRick: TL:DR: my point was just that you can't delete an element from an array in one instruction / operation, only as part of a pass over the whole array. – Peter Cordes Oct 28 '19 at 06:20

0 Answers0