Вы загружаете и сохраняете слова (16-битные значения), в то время как ваши символы по одному байту каждый.
Например, перед первой итерацией у вас есть это:
'4','5','1','A','B','D','4','5'
И после первой итерации у вас должно получиться следующее:
'5','4','1','A','B','D','4','5'
| |
\ /
swapped
Но в итоге вы сделаете следующее:
'5','1','1','A','B','D','4','5'
| |
\ /
AX is stored
'5','4','5','A','B','D','4','5'
| |
\ /
DX is stored
И так далее для остальной части строки.
Фиксированный и несколько упрощенный цикл обмена может выглядеть следующим образом:
EXCHANGE:
MOV DH,BYTE PTR [BX + DIM] ; First character in high byte of DX
MOV DL,BYTE PTR [BX + DIM+1] ; Second character in low byte of DX
MOV [BX + DIM],DX ; DX contains the byte-swapped pair
ADD BX,2 ; Move to next pair of characters
LOOP EXCHANGE