Reverse a string in place
The same program in M68K, MIPS, RISC-V, Z80.
A string reversed where it sits, with no second copy of it anywhere. Two addresses start at the two ends of the string, swap the bytes they point at, and walk towards each other until they meet in the middle.
Every byte is written exactly once, so the work is half the length of the string, and the loop needs no count: it stops when the two addresses have run into each other.
Type 402000 into the memory panel. The nine bytes read 79 6C 62 6D 65 73 73 61 00: ylbmessa,
and the terminator still sitting exactly where it was.
Keeping the zero out of the reversal is what LEN equ $ - text - 1 is for. $ - text is nine, every
byte the db line produced, and the - 1 takes the terminator back off, leaving eight characters to
reverse. Drop the - 1 and the zero gets swapped to the front, where it turns the string into an
empty one.
jae compares two addresses, which is why it is the unsigned condition: addresses are never
negative, and the signed jge would give a different answer on any address with its top bit set. The
comparison is at the top of the loop, which handles both ways the two can finish. An odd length string
ends with both addresses on the same middle byte, and jae is true. An even length one ends with them
crossed over, one past each other, and jae is true then too. A single character string never enters
the loop at all.
Four mov instructions do the swap, where xchg al, [rsi] would do it in half the lines. That is
deliberate. xchg with a memory operand carries an implicit lock prefix, which tells the
processor to hold the memory bus for the whole instruction so that nothing else in the machine can
touch that address in the middle of it. That guarantee is exactly what you want when two threads share
a counter, and it costs far more than four plain moves when, as here, nobody else is looking.