Home > Back-end >  How to swap chars in the string?
How to swap chars in the string?

Time:10-23

I sort a string, so I use bubble sorting. I need to swap chars, but they don't swap properly. Is that because of registers? (I use TASM). For example, I input string "zyx" and program crashes.

All my code: https://pastebin.com/3tGQzYQa

My code for input and bubble sorting (I think bubble sort has some issues. Program correctly inputs and outputs without bubble sorting. I use DOSBox 0.74-3):

.model small
.data
        message db   'String: $'
        string db 10 dup('$')
        tabSize db 5
        temp db 1
        tempValue db 1
        iterations db 1
.stack 256h
.code
main:
; some code
        lea dx, message ; load message to dx
        mov ah, 09h ; output message
        int 21h

        ; input string from user input
        mov ah, 0Ah
        lea dx, string 
        mov string, 10
        int 21h
        
        mov cl, string[1] - 1 ; length of the outter loop
        mov si, 2 ; start of chars at the string
bubbleSort:
        mov iterations, cl ; save length of the outter loop for an inner loop
        mov cl, string[1] - [si] - 1 ; get length of the inner loop
        push si ; save old value of the indexator
        mov si, 2 ; indexator for the new loop

        secondLoop:
                xor al, al ; flush al

                ; comparing string[si] and string[si   1]
                mov al, string[si]
                cmp al, string[si   1]
                jle passing ; if string[si] < string[si   1] go to passing

                ; else swap
                mov dl, string[si]
                mov al, string[si   1]
                mov string[si], al
                mov string[si   1], dl

                passing:
                        inc si
                loop secondLoop

        pop si ; return old value for si
        inc si ; increment it because of new iteration

        xor cl, cl
        mov cl, iterations ; return old length of the outter loop for the loop
        loop bubbleSort   
; some code
end main

Output with sorting

Output without sorting

CodePudding user response:

.data
   message db   'String: $'
   string db 10 dup('$')
   tabSize db 5
   temp db 1
   tempValue db 1
   iterations db 1
.stack 256h

The first problem is with the definition of string. This is meant to be the input structure for the DOS.BufferedInput function 0Ah. DOS expects to find the storage length in the first byte and will return the length of the actual input in the second byte. How buffered input works has the details.
What you have written for string translates to a 10-byte region of memory entirely filled with the number 36 (ASCII of '$'). Before input you change the first byte to 10, which will permit DOS to legally use the next 12 bytes for inputting purposes. The other variables tabSize, and temp are in risk of getting overwritten!
If you want to allow for an user input of 10 characters, then the correct definition is string db 11, 0, 11 dup(0).


The second problem is that you have several weird looking instructions that simply should not assemble.

mov cl, string[1] - 1 ; length of the outter loop

The length of the outerloop is given by the length of the string minus 1. In code this becomes: xor cx, cx mov cl, string[1] dec cx.

mov cl, string[1] - [si] - 1 ; get length of the inner loop

The length of the innerloop is equal to the current value of the outerloop iterator.

push [si]

Preserving the SI register is possible via push si.

inc si ; increment it because of new iteration

For every iteration of the outer loop will your ascending BubbleSort leave the greatest element at the high end of the array. By incrementing SI, you would be skipping an unsorted element at the low end of the array. After multiple edits to the question, this may no longer be true.

Try next code:

; Ascending BubbleSort
 xor  cx, cx
 mov  cl, string[1]
 dec  cx
outerLoop:
 push cx
 mov  si, 2
innerLoop:
 mov  al, string[si]
 mov  dl, string[si   1]
 cmp  al, dl
 jbe  passing                 (*)
 mov  string[si], dl
 mov  string[si   1], al
passing:
 inc  si
 loop innerLoop
 pop  cx
 loop outerLoop

(*) You are processing a string of characters. A character is represented by its ASCII code which is an unsigned number. Best use the unsigned conditional branch jbe JumpIfBelowOrEqual.

  • Related