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
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.