assembly program to sort in special way? help please? - arrays

8086 assembly language program that sorts an array as follows:
smallest value in the array should be placed in the first cell.
second smallest value in the last cell.
third smallest value in the second cell of the array.
fourth smallest value placed in the before-last cell of the
array.
• The above procedure continues until the array is fully sorted.
Note that in the above-described sorting technique, the large values in the initial array
will end up being placed at the middle part of the array
here is my code it sorting but in normal way :
org 100h
.MODEL SMALL
.DATA
TABLE DB 9,2,6,8,5,1
B DB 6 DUP(0)
VAL1 DB 5
NL DB ' ','$'
.CODE
MOV AX,#DATA
MOV DS,AX
LEA BX,TABLE
MOV DL,VAL1
LBL1:
LEA BX,TABLE
MOV CL,5
LBL2:
MOV AL,[BX]
MOV DL,[BX+1]
CMP AL,DL
JB LBL3
MOV [BX],DL
MOV [BX+1],AL
LBL3:
INC BX
LOOP LBL2
MOV DL,VAL1
DEC DL
MOV VAL1,DL
CMP DL,00
JNE LBL1
MOV CL,6
LEA BX,TABLE
DISPLAY:
LEA DX,NL
MOV AH,09H
INT 21H
MOV DL,[BX]
ADD DL,30H
MOV AH,02H
INT 21H
INC BX
INC BX
LOOP DISPLAY
MOV AH,4CH
INT 21H
ret

Replace:
mov cl, val1
by:
mov cl, [val1]
This way it moves the content of val1 (the number 5) to cl. In the code above, it would only move the offset of val1 to cl (the same as lea cl, val1).

Related

Printing an array but specific values highlighted {emu8086}

I want to print this array but also highlight specific characters from said array. This is my code:
include 'emu8086.inc'
.data
animales1 db 'BUBRPQYFODFZXIQ'
db 'MSVDJVQDTLOEATF'
db 'RCZPIFYGAZLPMFN'
db 'LVWKFFBKDXHFIUW'
db 'AOSEFQEMOOTGQUR'
db 'ELLWTGNJJKAJISJ'
db 'OVCOXLUEQTSDDSP'
db 'UEAEMTNYOLVYMGI'
db 'ORREPOMJZGYPHAI'
db 'IFTLCBJFVOYHLUB'
db 'WTOWZQFRAXQRLMR'
db 'KGNYIIHHHKFUKIJ'
db 'XMLSACGMVXEYSIT'
db 'TSOESQVSEQRFNPU'
db 'ODDQMDFWRGETDLY'
lenguajes2 db 'SLKFMBCULKVYUIM'
db 'TWCDQFYIVIKUXKB'
db 'GNIWEQBOSYEMDTJ'
db 'WDHFZZPUIEDERYQ'
db 'KMTGTKAKROMUSUV'
db 'BELBLLTUVJQHCRW'
db 'UPLUBYJKNUXORLF'
db 'SGMAOOEENBOGIWR'
db 'JVSTLPTEGPPNPJW'
db 'YINCASSEMBLYTTU'
db 'CHWTIOIWORDZDRV'
db 'BRZCNRAVRWAMUNU'
db 'KOMCOUKNGQEPQVS'
db 'XXRXJUJUBEXVGGA'
db 'MNKJQKZAACVCLDW'
char db 'a'
flag db 0
;Pez= 12,27,42
;Ave= 76,92,108
indx db 5,11,26,41,45 dup (' ')
.stack
.code
.start up
mov ax,0000h
mov bx,0000h
mov cx,0000h
mov dx,0000h
lea si, animales1
;call valueInArray
call printArrays
printArrays proc
mov bx,0000h
printArray:
mov dx,0000h
mov ah, 02h
mov dl,byte ptr[si+bx]
call valueinArray
cmp flag,1
jz printSpecial
int 21h
mov dl, 20h
int 21h
add bx, 1
add cl, 1
cmp cl,15
jz nextRow
jnz printArray
nextRow:
call nwLine
add ch,1
mov cl, 00h
cmp ch,15
jz finproc
jnz printArray
printSpecial:
lea di,char
mov byte ptr[di],dl
push ax
push bx
push cx
push dx
mov bp, offset char
mov dh,00h
mov al, 1
mov bh, 0
mov bl, 1111_0000b
mov cx, 1; calculate message size.
mov dx,0000h
mov ah, 13h
int 10h
mov dl, 20h
mov ah, 02h
int 21h
pop dx
pop cx
pop bx
pop ax
add bx, 1
add cl, 1
cmp cl,15
jz nextRow
jnz printArray
finproc:
ret
printArrays endp
nwLine PROC
MOV AH,02h
MOV DX,0Ah; imprime asscii 10 (nueva linea)
INT 21h
MOV DX,0Dh; imprime asscii 13 (retorno de carro)
INT 21h
RET
nwLine ENDP
valueInArray proc
mov flag, 0
mov di,0001h
iterar:
mov dh, indx[di]
cmp dh,20h
jz finvalueproc
cmp bl,dh
jz found
add di,1
jmp iterar
found:
mov flag,1
jmp finvalueproc:
finvalueproc:
ret
valueInArray endp
exit:
end
As you can see, the array 'indx' have the positions of the chars (The first number is the effective lenght of said array) that I want to highlight so I check if bx is in the position of said character to print it highlighted.
I have two problems at the moment, the first one is the highlighted characters are printing in a kinda random position and that messes up the rest, but I think I know why the position of the highlighted character that prints is wrong, because the interrupt that I use uses dh and dl as positioners but I do not know how to make it so it continues the flow of the rest. The second problem is that the character that prints is wrong, if you run it and check the variable char, it has an 'Z' but it prints a 'T'. I really need help. Pretty please. :(
indx db 5,11,26,41,45 dup (' ')
It could be that this line is not what you think it is!
Reading your explanation I think you really meant:
indx db 5, 11, 26, 41, 45, ' '
That is the length of the array which is 5, then followed by 4 offsets to the highlighted characters and 1 space character as a list terminator.
the first one is the highlighted characters are printing in a kinda random position and that messes up the rest, but I think I know why the position of the highlighted character that prints is wrong, because the interrupt that I use uses dh and dl as positioners but I do not know how to make it so it continues the flow of the rest.
Because your code to output the highlighted character uses mov dx,0000h, the BIOS function 13h places the character in the upperleft corner of the screen and the other, 'normal' characters will continue from there.
All you have to do is to ask BIOS where the cursor is at that moment using function 03h:
Replace
mov cx, 1; calculate message size.
mov dx,0000h
mov ah, 13h
int 10h
by
mov ah, 03h ; BIOS.GetCursorAndConfiguration
int 10h ; -> CX DX
mov cx, 1 ; message size
mov ah, 13h ; BIOS.WriteString
int 10h
Function 13h fetches from ES:BP. Did you setup the ES segment register?
The second problem is that the character that prints is wrong, if you run it and check the variable char, it has an 'Z' but it prints a 'T'.
Probably resolving the first problem will also resolve the second one.
There's a better, less convoluted way to output your highlighted character.
printSpecial:
push ax
push bx
push cx
mov cx, 1 ; ReplicationCount
mov bx, 00F0h ; DisplayPage 0, Attribute BlackOnBrightWhite (11110000b)
mov al, dl ; Character
mov ah, 09h ; BIOS.WriteCharacterAndAttribute
int 10h
mov ah, 0Eh ; BIOS.TeletypeCharacter
int 10h
pop cx
pop bx
pop ax
...
Function 09h will write your character with the colors that you need, and then function 0Eh will advance the cursor normally.

How to sort an array using stack in assembly

I want to sort an array while using the stack:
so first things first I pushed it all into the stack.
then I'm locating the minimum element in the stack, swapping it with the top element popping it out and move it back to the array.
but something isn't right and about halfway there it got messed up (DI is one index below than what it should really be)
data segment
a db 5h,12h,6h,4h,9h
len equ $-a
loop_counter db len
min_index dw 0
min db ?
ends
stack segment
dw 128 dup(0)
ends
code segment ;TODO: Locate min in stack xchg it with top element copy to array and pop it :|
start:
mov ax, data
mov ds, ax
mov bx,0
mov cx,0
mov cl,loop_counter
push_arr_to_stack:
mov al,a[bx]
push ax
inc bx
loop push_arr_to_stack
mov bx,len-1
mov ax,0
mov cl,loop_counter
mov bp,sp
mov ax,[bp]
mov bx,[bp]
mov di,0
mov dx,0
mov si,2
mov di_check,len-loop_counter
find_min_to_arr:
cmp bx,ax
jb new_min
mov bx,[bp+si]
add si,2
loop find_min_to_arr
mov min,al
xchg a[di],al
jmp pop_min
new_min:
mov ax,bx
mov bx,[bp+si]
mov min_index,si
sub min_index,2
add si,2
dec cx
jmp find_min_to_arr
pop_min:
mov dx,[bp]
xchg di,min_index
mov [bp+di],dx
xchg di,min_index
pop dx
mov dx,0
inc di
mov si,0
cmp di,len
je b
dec loop_counter
mov cl,loop_counter
jmp find_min_to_arr
b:
mov ax, 4c00h ; exit to operating system.
int 21h
ends
end start
first I pushed it all into the stack.
This part is fine although for speed reasons you should forget about loop .. and replace it with dec cx followed by jnz ..
then I'm locating the minimum element in the stack, swapping it with the top element popping it out and move it back to the array.
Here your code gets very complicated and it contains many errors. Also the code does not perform true swapping between the located minimum and the element at the top of the stack.
I tried amending your code but as is often the case, it is beyond repair. Below is my rewrite that you should study, not just copy!
I have defined the loop_counter a word variable because that's easier. Additionally I kept it in the DX register that was sitting there doing nothing...
Pushing it all into the stack
mov bx, dx
push_arr_to_stack:
mov al, a[bx-1]
push ax
dec bx
jnz push_arr_to_stack
I push the array in reverse so the stack has the elements in the same order as the original array. This is not necessary for the task, but it is simpler and it leaves the BX register at zero for use below.
Locating the minimum in the stack
Again:
mov bp, sp
xor si, si
mov al, [bp+si] ; Chosen minimum
mov di, si ; Remember its position
mov cx, dx
dec cx ; N elements = N-1 compares
jz .c
.a: add si, 2
cmp al, [bp+si]
jbe .b
mov al, [bp+si] ; New minimum
mov di, si ; Remember its position
.b: dec cx
jnz .a
Swapping it with the top element
.c: xchg al, [bp]
mov [bp+di], al
Popping it out and moving it back to the array
pop ax
mov a[bx], al
inc bx
dec dx
jnz Again
The important thing here is that the above exactly does what the task description said.

TASM assembly array being funky and not working

Basically....
I'm trying to make a snake game in TASM assembly. currently, main problem is the fact that the array of the snake game (a 400 cell array of bytes) is being completely funky.
example:
when i try to put it later on in the DATASEG (like being one of the last vars defined) and i try to paint the array for the start of the game, it loads up as if some random cells have value different than 0 (they should not). another problem is when i change the value of 1 random cell to generate an apple, it sometimes goes and paints 2 apples, meaning something went awry...
This is how i defined my array: GameArray db 400 dup(0)
This is how i mov array: mov bx, offset GameArray
also, the timer just doesn't seem to work. what i have right now in the code are just the functions and the attempt at seeing if the timer works:
`.286
IDEAL
model small
stack 100h
DATASEG
GameArray db 400 dup(0) ;20x20 array for the snake game. need to be first variable for some reason, or cell values are jumbled up. wierd...
ApplePresent db 0 ;incase 2 or more cells with applevalue, disregard the later cells and make them empty squares
seconds db 99 ;variable for timer to check in how many miliseconds there is change.
One db 1 ;used as number '1' as word so bx which array is moved to will have no problems.
AppleValue db 255 ;used as number '256' as word so bx which array is moved to will have no problems.
Zero db 0 ;used as number '0' as word so bx which array is moved to will have no problems.
PointGained db 0 ;Boolean var to check if point was gained in the movement. if so, snake will be grown.
NumCell dw 0 ;NumCell represents the cell in the array which the snake's head will be going to.
Score db 0 ;keeps score of the game.
xArr dw 10 ;x coordinate of head (value 5 at start) at start of game. (x of array)
yArr dw 9 ;y coordinate of head (value 5 at start) at start of game. (y of array)
SnakeHead db 5 ;SnakeHead value will be copied to element of array snake head will go to.
xDraw dw ? ;x coordinate for drawing screen
yDraw dw ? ;y coordinate for drawing screen
xDrawlim dw ? ;x coordinate for drawing screen limit of box
yDrawlim dw ? ;y coordinate for drawing screen limit of box
Direction db 1 ;1 = right, 2 = up, 3 = left, 4 = down. gets value from last click of WASD keys
Clock equ es:6ch ;looks at clock memory segment.
CODESEG
proc ApplesFix ;FUnction to fix if there are 2 or more cells with value of 255 in them. if so, reset the value of the array cell to 0.
pusha
mov bx, offset GameArray
mov ax, 400
ApplesFixLoop:
mov cl, [AppleValue]
cmp [bx], cl
je IncrementApplePresent
inc bx
dec ax
jnz ApplesFixLoop
jmp EndFix
IncrementApplePresent:
inc [ApplePresent]
cmp [ApplePresent],1
jg FixCell
inc bx
dec ax
jnz ApplesFixLoop
jmp EndFix
FixCell:
mov cl, [Zero]
mov [bx], cl
inc bx
dec ax
jnz ApplesFixLoop
EndFix:
popa
ret
endp ApplesFix
proc RandApple
pusha ;pushes all registers. never knew the command so only using it now.
push [Numcell]
RandGen:
mov [NumCell],0
mov ax, 40h
mov es, ax
mov cx, 10
mov bx, 0
random_loop_apple:
mov ax, [Clock]
mov ah, [byte cs:bx]
xor al, ah
and al, 11111111b
xor ah, ah
mov [NumCell], ax
add [NumCell], 11
loop random_loop_apple
mov bx, offset GameArray
add bx, [NumCell]
mov cl, [Zero]
cmp [bx], cl
je GenerateApple
jmp RandGen
GenerateApple:
mov cl, [AppleValue]
mov [bx], cl
pop [Numcell]
popa
ret
endp RandApple
proc KeyPress ;function which gets key press from WASD and will change var 'Direction' according to it.
push ax
mov ah, 1d
int 21h
Wait_for_Data:
cmp al, 87;'W'
je MovingUp
cmp al, 65;'A'
je MovingLeft
cmp al, 83;'S'
je MovingDown
cmp al, 68;'D'
je MovingRight
jmp Wait_for_Data
MovingUp:
mov [Direction], 2d
jmp EndKeyPress
MovingLeft:
mov [Direction], 3d
jmp EndKeyPress
MovingDown:
mov [Direction], 4d
jmp EndKeyPress
MovingRight:
mov [Direction], 1d
jmp EndKeyPress
EndKeyPress:
pop ax
ret
endp KeyPress
proc MoveHead ;Head value will be copied into the array cell which snake moves to.
pusha
mov bx, offset GameArray
add bx, [NumCell]
mov cl, [SnakeHead]
mov [bx], cl
popa
ret
endp MoveHead
proc DirectionSnake ;proc for changing x,y values of array to know which square head value will be copied to.
cmp [Direction], 1d
je MoveRight
cmp [Direction], 2d
je MoveUp
cmp [Direction], 3d
je MoveLeft
cmp [Direction], 4d
je MoveDown
MoveRight:
add [xArr] ,1d
cmp [xArr], 19d
jg OtherSideRight
jmp EndDirectionSnake
MoveUp:
sub [yArr], 1d
cmp [yArr], 0d
jb OtherSideUp ;function for making snake head appear at the highest layer if snake goes down out of boundaries. (same with labels of same name, just for different function)
jmp EndDirectionSnake
MoveLeft:
sub [xArr], 1d
cmp [xArr], 0d
jb OtherSideLeft
jmp EndDirectionSnake
MoveDown:
add [yArr], 1d
cmp [yArr], 19d
jg OtherSideDown
jmp EndDirectionSnake
OtherSideRight:
mov [xArr], 0d
jmp EndDirectionSnake
OtherSideUp:
mov [yArr], 19d
jmp EndDirectionSnake
OtherSideLeft:
mov [xArr], 19d
jmp EndDirectionSnake
OtherSideDown:
mov [yArr], 0d
EndDirectionSnake:
ret
endp DirectionSnake
proc findHeadXY ;find xy coordinate of the cell in array which head will be going to
push ax ;preserving value of ax by pushing him into stack and popping him at the end of function.
mov ax, [xArr]
mov [NumCell], ax ;NumCell represents the cell in the array which the snake's head will be going to.
mov ax, [yArr]
FindArrayCelly: ;label for loop of finding the array cell's y value that snake head is going to be copied into.
add [NumCell], 20d
sub ax, 1d
jnz FindArrayCelly
pop ax
ret
endp findHeadXY
proc MoveAction ;function will find whats inside the cell snake head will be going to and see if snake eats apple and moves, regular movement or lose.
push bx
push cx
mov bx, offset GameArray
add bx, [NumCell] ;goes to the cell which the snake head will be moving to.
mov cl, [AppleValue]
cmp [bx], cl
je SnakeEatsApple
mov cl, [Zero]
cmp [bx], cl
je SnakeMoves
jmp GameLost
SnakeEatsApple:
add [Score], 1d ;if apple is eaten score is increased by 1.
mov [PointGained], 1d ;sets boolean to 1 meaning 'True', snake will lengthen
cmp [Score], 255d
je GameWon
call MoveHead
SnakeMoves:
call MoveHead
GameLost:
mov ax, 0c00h ;replicating exit interrupt.
int 21h
GameWon:
mov ax, 0c00h ;replicating exit interrupt.
int 21h
EndMoveAction:
pop cx
pop bx
ret
endp MoveAction
proc BlackSquare ;when array element has value which is 0, draw white square
push cx
push dx
mov cx,[xDraw]
mov dx,[yDraw]
mov al, 15d
loopboxB:
mov bh,0h
mov ah,0ch
int 10h
inc cx
cmp cx,[xDrawlim]
jne loopboxB
mov cx,[xDraw]
inc dx
cmp dx,[yDrawlim]
jne loopboxB
pop dx
pop cx
ret
endp BlackSquare
proc SnakeSquare ;when array element has value which is not 0 or 256, draw green square (green color)
push cx
push dx
mov cx,[xDraw]
mov dx,[yDraw]
mov al, 2d ;al assigned different value for different color
loopboxS:
mov bh,0h
mov ah,0ch
int 10h
inc cx
cmp cx,[xDrawlim]
jne loopboxS
mov cx,[xDraw]
inc dx
cmp dx,[yDrawlim]
jne loopboxS
pop dx
pop cx
ret
endp SnakeSquare
proc AppleSquare ;when array element has value which is 256, draw yellow square
push cx
push dx
mov cx,[xDraw]
mov dx,[yDraw]
mov al, 14d ;al assigned different value for different color
loopboxA:
mov bh,0h
mov ah,0ch
int 10h
inc cx
cmp cx,[xDrawlim]
jne loopboxA
mov cx,[xDraw]
inc dx
cmp dx,[yDrawlim]
jne loopboxA
pop dx
pop cx
ret
endp AppleSquare
proc DrawScreen ;draws screen according to value in array elements.
pusha
mov bx, offset GameArray
mov ax, 0d
mov [xDraw], 121d ;starting values for painting screen
mov [ydraw], 101d
mov [xDrawlim], 130d
mov [yDrawlim], 110d
CheckElementValue:
mov cl, [Zero]
cmp [bx], cl
je CallBlackSquare ;goes to label to call function BlackSquare
mov cl, [AppleValue]
cmp [bx], cl ;cx is copying AppleValue since comparing memory (var) to memory (array which is copied in bx) is illegal.
je CallAppleSquare ;goes to label to call function AppleSquare
jmp CallSnakeSquare ;goes to label to call function SnakeSquare
CallBlackSquare:
call BlackSquare
add [xDraw], 10d
add [xDrawlim], 10d
inc ax
cmp ax, 400d
je EndDrawingScreen
add bx,1
cmp [xDrawlim], 330d
je DropLine
jmp CheckElementValue
MidJumP:
jmp CheckElementValue
CallAppleSquare:
call AppleSquare
add [xDraw], 10d
add [xDrawlim], 10d
inc ax
cmp ax, 400d
je EndDrawingScreen
add bx,1
cmp [xDrawlim], 330d
je DropLine
jmp CheckElementValue
CallSnakeSquare:
call SnakeSquare
add [xDraw], 10d
add [xDrawlim], 10d
inc ax
cmp ax, 400d
je EndDrawingScreen
add bx,1
cmp [xDrawlim], 330d
je DropLine
jmp CheckElementValue
DropLine:
add [yDraw], 10d
add [yDrawlim], 10d
mov [xDraw], 121d
mov [xDrawlim], 130d
cmp [yDrawlim], 310d
jne MidJumP
EndDrawingScreen:
popa
ret
endp DrawScreen
proc CycleChange ;the procedure reduces all cells in array which value is greater than 0 by 1, so tail of the snake will get erased after new head is formed.
pusha
mov bx, offset GameArray
mov ax, 400d
CheckArray:
cmp [word ptr bx], 0 ;checks current element of array looked at and checks if equal to 0. need to add that will not reduce value if its 256 as well.
jne DecreaseCellValue
add bx, 1d
dec ax
jz EndCycleChange
DecreaseCellValue:
mov cl, [One]
sub [bx], cl
add bx, 1d
dec ax
jmp CheckArray
EndCycleChange:
popa
ret
endp CycleChange
proc ResetArray ;restore all array values to 0.
pusha
mov bx, offset GameArray
mov ax, 400d
ResetArrayL:
mov cl, [Zero]
mov [byte ptr bx], cl
inc bx
dec ax
jnz ResetArrayL
popa
ret
endp ResetArray
start:
mov ax, #data
mov ds, ax
GameStart:
mov bx, offset GameArray
add bx, 210
push cx
mov cx, [word ptr SnakeHead]
GenerateSnake: ;puts snake of length 5 in the array.
mov [word ptr bx], cx
inc bx
loop GenerateSnake
GenerateStartingApple:
call RandApple ;Puts apple randomly in cell of array before starting the game.
call ApplesFix
mov ax,012h
int 10h ;640 x 480 16 colors. graphic mode interrupt.
secstart:
call DrawScreen
mov ah,02ch ; Get current second
int 021h
mov bh,dh ; Store current second
readloop:
mov ah,02ch ; Get new time. Seconds are stored in dh
int 021h
sub dh,1 ; Subtract 1 from new second. Giving 1 Secs for input.
GoBackCheck: ;if no key has been pressed, until second is over input from keyboard will be checked.
cmp bh,dh
je SecondPassed ; Exit when DH is finally equal to BH.
mov ah,06h ; Function 06h of INT 021 will directly read from the Stdin/Stdout
mov dl,0ffh ; Move 0ff into the DL register to read from the keyboard
int 21h
jz GoBackCheck ; If the zero flag of the FLAGS register is set, no key was pressed.
call KeyPress
jmp GoBackCheck
SecondPassed: ;here snake moves and checks if you lost/won game.
call findHeadXY
call MoveHead
GoBack:
jmp secstart
exit:
mov ax, 0c00h
int 21h
END start`

Sort 10 integer numbers read from keyboard and display in ascending order

I managed to write this code for turbo debugger in assembly language which is meant to sort 10 integer numbers read from the keyboard and display them in ascending order but it keeps looping B to infinite..
The code is :
.model small
.stack 100h
.data
strg1 DB 'Insert numbers: $'
strg2 DB 'Sorted numbers: $'
Arr Db 10 dup(?)
v dw ?
.code
main proc
mov ax,#data
mov ds,ax
mov ah,9
lea dx,strg1
int 21h
mov dl,0ah
mov ah,2
int 21h
;inputs
mov di,0
mov cx,10
Input_loop:
mov ah,1
int 21h
mov arr[di],al
mov dl,0ah
mov ah,2
int 21h
inc di
loop Input_loop
mov v,0
sort:
mov di,0
mov cx,10
sub cx,v
B:
mov al,Arr[di]
cmp al,Arr[di+1]
jng C
mov al,Arr[di]
xchg al,Arr[di+1]
mov Arr[di],al
c:
inc di
loop B
inc v
cmp v,10
jne sort
;Output
mov ah,9
lea dx,strg2
int 21h
mov dl,0ah
mov ah,2
int 21h
mov di,0
mov cx,10
Output_loop:
mov dl,Arr[di]
mov ah,2
int 21h
inc di
mov dl,0ah
mov ah,2
int 21h
loop output_loop
mov ah,4ch
int 21h
main endp
end main
It is running perfectly, I can enter my desired numbers to be sorted, and then when it reaches c: , it just keeps looping B to infinite and it really makes me mad . Do you have any idea what went wrong and how can I fix it ?
Arr Db 10 dup(?)
v dw ?
In an array that has 10 elements, you can do 9 pairwise comparisons at most.
Your code does 10 comparisons and will move whatever byte is stored after the array, and that is probably a zero, down in memory!
Initialize v at 1:
mov v, 1
sort:
This is the only modification that I made and your program ran perfectly in DOSBox. I assembled the source using TASM 4.1 followed by TLINK
A better BubbleSort
Don't use BubbleSort, better algorithms exist! :-)=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Better use a register like SI instead of a memory based variable v.
Use downcounting for the outer loop count.
Because your elements are byte-sized, you can read and write two elements together.
Keep addressing modes simplest/shortest (using [di] instead of Arr[di]).
Avoid the slow LOOP instruction.
Use meaningful names for your labels.
Avoid using XCHG between a register and memory.
Use unsigned conditional jumps after comparing unsigned quantities like characters "0" to "9" (using jna instead of jng).
mov si, 10-1
Outer:
mov di, offset Arr
mov cx, si
Inner:
mov ax, [di]
cmp al, ah
jna Skip
xchg al, ah
mov [di], ax
Skip:
inc di
dec cx
jnz Inner
dec si
jnz Outer

Array Bubble Sort in Assembly Language

Problem is that why is only sorting the last element and then putting 5 on every index?
I am posting for the first time so I apologize if my question is unclear.
arr BYTE 5,4,3,2,1
arr1 BYTE 5 DUP(?)
temp BYTE ?
.code
main PROC
mov ecx,LENGTHOF arr
mov esi,Offset arr
mov edi,offset arr+1
L1:
mov al,[esi]
mov edx,ecx
mov ecx,4
L2:
mov bl,[edi]
cmp al,bl
JG L3
jmp L5
L3:
mov temp,al
mov [esi],bl
;mov dl,temp
mov [edi],al
inc edi
L5:
loop L2
mov ecx,edx
inc esi
loop L1
;Printing my array
mov ecx,LENGTHOF arr
mov al,arr[0]
CALL dumpRegs
mov al,arr[1]
CALL dumpRegs
mov al,arr[2]
CALL dumpRegs
mov al,arr[3]
CALL dumpRegs
CALL dumpRegs
exit
main ENDP
END main
Problem is that why is only sorting the last element and then putting 5 on every index?
Your L2 InnerLoop works exclusively with the 1st array element since, once it is loaded in AL, you don't advance the pointer in ESI. And because this particular value happens to be the greatest value in the array, it gets stored everywhere.
Your L2 InnerLoop also works with a fixed count of 4 where it should be working with a count of CurrentOuterLoopCount - 1.
The correct solution does not need the 2 different pointer registers. The array elements that are to be compared are always adjacent to each other and so a simple offset of +1 will do the trick.
This is a working BubbleSort. Find out how it works, don't just copy it!
arr BYTE 5,4,3,2,1
.code
main PROC
mov ecx, LENGTHOF arr
sub ecx, 1
jbe Done ; Array is empty or has but 1 element
OuterLoop:
mov edx, ecx ; 5 elements means 4 comparisons
mov esi, Offset arr
InnerLoop:
mov al, [esi]
mov bl, [esi+1]
cmp al, bl
jng NoSwap
mov [esi], bl
mov [esi+1], al
NoSwap:
inc esi
dec edx
jnz InnerLoop
dec ecx ; Next time 3 comparisons, then 2, and then 1
jnz OuterLoop
Done:

Resources