If you just want the answer without the explanation, scroll to the bottom of this post.
The [register] notation stands for "take the value stored in register and interpret it as an address". If the addressed entity size is ambiguous, it can be clarified using DWORD PTR [register] for DWORD-sized pointers (and similarly for other pointer sizes).
mov BL, [EAX]
This line treats the value in the EAX register as a pointer to a single byte (the size of BL), reads a byte from that address and stores it in BL.
inc EAX
This line increments the value of EAX, effectively advancing to the next byte.
mov [EDX], BL
This line treats the value in the EDX register as a pointer to a single byte (again, the size of the other operand tells us this), and writes a byte that is stored in BL to that address.
inc EDX
This line increments the value of EDX, advancing to the next byte.
With all this information, we can see that this sequence basically copies a byte from one address to another. Most likely it is used in a loop such as string copy or memory copy. If there's a line similar to test BL, BL afterwards to determine if the copied byte was NULL, it's most likely a string copy; if there's a length/address check instead - it's probably a memory/buffer copy that works on a specified amount of bytes.
In C parlance, this can be represented as:
char t; // BL
char *src; // EAX
char *dst; // EDX
// initialize src and dst here
t = *src;
++src;
*dst = t;
++dst;
Or, as K&R put it ever so tersely:
*dst++ = *src++;
strcpyloop,*dst++ = *src++?[EDX]does not stand for "the EDX register". It stands for "the address pointed to by the EDX register". The constrained you mentioned is valid, and in this case the instructionmov [EDX], BLis interpreted as "move the lowest byte of theEBXregister to the byte at the address pointed to by (the value of) theEDXregister."