DYNASM RevStr(BYVAL s AS STRING) AS STRING // get length of string // divide by two // setup pointers to head and tail // iterate from 1 to (length \ 2) // swap head with tail // increment head pointer // decrement tail pointer ENTER 0, 0 // = PUSH EBP: MOV EBP, ESP PUSH EBX // by Windows convention EBX, EDI, ESI must be saved before modification MOV EAX, s // get string pointer MOV ECX, EAX // duplicate it .WHILE BYTE PTR [ECX] <> 0 INC ECX // propagate to tail .WEND MOV EDX, ECX // duplicate tail pointer DEC EDX // set it to last byte before trailing zero SUB ECX, EAX // get length in ECX in 1 CPU cycle SHR ECX, 1 // get length \ 2 in 1 CPU cycle; that's the beauty of power-of-two division .WHILE ECX > 0 MOV BL, [EDX] // no need to XOR; just overwrite BL and BH contents MOV BH, [EAX] // DynAsm deduces data size from destination register sizes MOV [EDX], BH // ditto, source register sizes MOV [EAX], BL INC EAX // propagate pointers DEC EDX DEC ECX // decrement counter .WEND // point to start of string again MOV EAX, s // MOV = 1 CPU cycle, PUSH + POP = 2 CPU cycles POP EBX // by Windows convention ESI, EDI, EBX must be restored if modified LEAVE // = POP EBP RET END DYNASM