Array Bubble Sort in Assembly Language - arrays

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:

Related

Print array in Asembly x86

I have elements loaded in stack and I need to move them to array. My code looks like this:
%include "asm_io.inc"
segment .data
array db 100 dup(0)
length db 0
segment .text
global _asm_main
extern getchar
_asm_main:
enter 0, 0
pusha
call getchar
char_loop:
mov ebx,10
sub eax, '0'
mul ebx
mov ebx, eax
call getchar
sub eax, '0'
add eax, ebx
push eax
inc BYTE[length]
call getchar
cmp eax, 10
je fill_array
cmp eax, 13
je fill_array
cmp eax, 32
je skip_spaces
jmp char_loop
skip_spaces:
call getchar
cmp eax, 32
je skip_spaces
jmp char_loop
fill_array:
mov ecx, [length]
mov ebx, array
l1:
pop eax
mov [ebx], eax ; should be al instead of eax
inc ebx
call print_int
call print_nl
loop l1
print_array:
mov ecx, [length]
mov ebx, array
l2:
mov eax, [ebx] ; should be al instead of eax
call print_int
call print_nl
inc ebx
loop l2
_asm_end:
call print_nl
popa
mov eax, 0
leave
ret
print_int in asm_io.asm is
print_int:
enter 0,0
pusha
pushf
push eax
push dword int_format
call _printf
pop ecx
pop ecx
popf
popa
leave
ret
Where int_format is int_format db "%i",0
Length and values in stack are correct, I had them printed but when I try to print array only last value is correct. Other values are random numbers. I tried combinations of registers of different sizes but it did not work. I think that error has to do something with size of registers or size of array.
Answer here:
As #xiver77 said in comments I was writing into array 4 bytes instead 1 byte. One element in array has 1 byte and I tried to write 4 bytes. That creates overflow of bites and change other elements in array. Instead mov [ebx], eax should be mov [ebx], al and mov eax, [ebx] for printing should be mov al [ebx].

Sorting through an array after filling in x86 MASM assembly language

can anyone help me with this problem, I'm new to assembly language and somewhat stuck on what to do next. Here's the code:
.data
evenStart dword 11h
oddStart dword 20h
darray dword 15 dup (?)
.code
main PROC
mov esi, OFFSET darray
xor ecx, ecx
L1:
mov ebx, OFFSET evenStart
test cl,1
jz iseven
mov ebx, OFFSET oddStart
iseven:
mov eax, [ebx]
inc dword ptr [ebx]
mov dword ptr [esi + 4*ecx],eax
inc ecx
cmp ecx,15
jb L1
exit
main ENDP
END main
So the project requires me to fill the uninitilized array, which I did. But then it also ask me to sort through this array in descending order and then put the middle elements of the array into the eax register and call DumpRegs. This is the part where I got stuck in. Any help on how to proceed would be great. Thank you!
Next Bubble Sort uses nested loops. Because your array has 15 elements, the outer loop can do 14 comparisons during its 1st iteration. With each iteration of the outer loop it has to do 1 comparison less because the smallest element has bubbled towards the end of the array.
mov ebx, 15-1 ; Outer loop iteration count
OuterLoop:
mov esi, offset darray
mov ecx, ebx ; Inner loop iteration count
InnerLoop:
lodsd
mov edx, [esi]
cmp eax, edx
jge Skip
mov [esi-4], edx ; Swap these 2 elements
mov [esi], eax
Skip:
dec ecx
jnz InnerLoop
dec ebx
jnz OuterLoop
The unsorted array:
11h, 20h, 12h, 21h, 13h, 22h, 14h, 23h, 15h, 24h, 16h, 25h, 17h, 26h, 18h
The sorted array:
26h, 25h, 24h, 23h, 22h, 21h, 20h, 18h, 17h, 16h, 15h, 14h, 13h, 12h, 11h
In this array with an odd number of elements (15), the element indexes range from 0 to 14. There is a true middle element at index 7.

Sorting array in x86 assembly language

I have to sort an array in descending order using parameters on the stack to an array and an array size. I passed the size by value at ebp+12 and the array by reference at ebp+8.
I know the code is kind of all over the place, but I'm just trying to get to something that works and I can try to clean it up from there.
I've been debugging and it seems to iterate through as I want it to, but my array isn't being sorted. I've been banging my head against this for hours, so any guidance would be greatly appreciated.
The pseudo-code algorithm I'm trying to follow is:
for(k=0, k<arrlength-1,k++)
I=K
for(J=k+1,J<arrlength,J++)
if(arr[j]>arr[i])
I=J
xchg(arr[k], arr[i])
And this is my attempt to implement it in x86 assembly:
;------------------------------------------------
sortlist PROC
;Sorts an array of specified size into descending order
;Receives: DWORD request value, address of an array
;Returns: array of size request, sorted in descending order
;------------------------------------------------
.data
first DWORD ?
next DWORD ?
.code
push ebp
mov ebp, esp
mov ecx, [ebp+12]
mov edi, [ebp+8]
mov eax, 0
mov ebx, 0
mov edx, 0
mov esi, 0
dec ecx ;loop for array length - 1
L1:
add edi, ebx ;ebx = 0 first loop, 4 all remaining loops
mov eax, [edi] ;get the value of the first element
mov first, edi ;store address of first element in first
mov next, edi
push ecx
push edi
L2:
add edi, 4 ;move to next element in array
mov edx, [edi] ;set value of next element to edx
cmp [next], edx ;compare element to next element
jg nxt
mov next, edi ;If less than, move address of greater to next
nxt:
loop L2
mov eax,[next] ;move values pointed to by 1st & next to regs
mov ebx,[first]
mov [first],eax ;move values(swapped) to addresses
mov [next],ebx
mov ebx,4
pop edi
pop ecx
loop L1
pop ebp
ret 8
sortlist ENDP

How to move and display array values from one to another in Assembly Language?

I am trying to move the values in Array1 to Array2, and then display them. I have been working on this and could not figure it out at all. Would anyone please help me? Thanks
INCLUDE Irvine32.inc
INCLUDE macros.inc
.data
Array1 DWord 2,4,6,8,10
Array2 DWord 5 Dup(0)
.code
main PROC
mov edx, OFFSET Array1
mov esi, OFFSET Array2
mov ecx, LENGTHOF Array1
mov eax, 0
Call Dumpregs
Call Dumpregs
L1:
mWrite "Hello"
Call CRLF
Loop L1
Call Dumpregs
L2:
mov eax, [edx]
mov [esi], eax
add esi, 4
add edx, 4
Loop L2
exit
main ENDP
END main
Your L2 loop cannot produce the desired result since the preceding code wiped ECX clean (You used loop L1). To copy the array you need to re-initialize ECX. Also it's best to setup the pointers EDX and ESI close to this L2 loop because perhaps there is a risk of them being modified by all those preceding (macro)calls!
mov edx, OFFSET Array1
mov esi, OFFSET Array2
mov ecx,5
L2:
mov eax,[edx]
mov [esi],eax
add esi, 4
add edx, 4
loop L2

32bit assembly - insertion sort doesn't work properly

My task here is to add a code that sorts the array with insertion sort.
'printf' function prints a string
printArray prints the array
For some reason the array doesn't get sorted, and i cant find the reason why.
Help will be appreciated.
main:
push MSG ; print welcome message
call printf
add esp,4 ; clean the stack
call printArray ;print the unsorted array
;;;;;;;;;;add code here;;;;;;;;;;
mov eax,1
loop1:
mov ebx, array
add ebx, eax
loop2:
mov esi, ebx
dec esi
mov esi, [esi] ;esi holds the value before what ebx points to
cmp [ebx], esi
ja endLoop2
mov edx, esi
mov esi, ebx
dec esi
mov ecx, [ebx]
mov [esi], ecx
mov [ebx], edx
dec ebx
cmp ebx, array
ja loop2
endLoop2:
inc eax
cmp eax, 11
jbe loop1
;;;;;;;end of your code;;;;;;;;;;;;;;
call printArray
mov eax, 1 ;exit system call
int 0x80
If your array is full of 1 byte values, use movb instead of mov when loading and storing to memory.

Resources