Skip to content

Commit da95ae7

Browse files
Gathrosleios
authored andcommitted
Bubble sort in X86-64 Assembly (#368)
* Adding x86 assembly to book.json * Adding bubble_sort.asm * Updaing bubble_sort.md * changing x86 to x86-64 * Adding x86-64 bubble sort * Adding bubble_sort.s
1 parent 285e3db commit da95ae7

File tree

3 files changed

+114
-0
lines changed

3 files changed

+114
-0
lines changed

book.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,10 @@
136136
"lang": "nim",
137137
"name": "Nim"
138138
},
139+
{
140+
"lang": "x64",
141+
"name": "X86-64 Assembly"
142+
},
139143
{
140144
"lang": "f90",
141145
"name": "Fortran90"

contents/bubble_sort/bubble_sort.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ This means that we need to go through the vector $$\mathcal{O}(n^2)$$ times with
5050
[import:3-28, lang:"lisp"](code/lisp/bubble_sort.lisp)
5151
{% sample lang="nim" %}
5252
[import:5-9, lang:"nim"](code/nim/bubble_sort.nim)
53+
{% sample lang="x64" %}
54+
[import:44-110, lang:"x64"](code/x64/bubble_sort.s)
5355
{% sample lang="f90" %}
5456
[import:19-40, lang:"fortran"](code/fortran/bubble.f90)
5557
{% sample lang="scala" %}
@@ -111,6 +113,8 @@ Trust me, there are plenty of more complicated algorithms that do precisely the
111113
[import, lang:"lisp"](code/lisp/bubble_sort.lisp)
112114
{% sample lang="nim" %}
113115
[import, lang:"nim"](code/nim/bubble_sort.nim)
116+
{% sample lang="x64" %}
117+
[import, lang:"x64"](code/x64/bubble_sort.s)
114118
{% sample lang="f90" %}
115119
[import, lang:"fortran"](code/fortran/bubble.f90)
116120
{% sample lang="scala" %}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
.intel_syntax noprefix
2+
3+
.section .rodata
4+
array:
5+
.align 16
6+
.int 1, 45, 756, 4569, 56, 3, 8, 5, -10, -4
7+
.equ array_len, (.-array) / 4
8+
array_fmt: .string "%d "
9+
lf: .string "\n"
10+
unsorted: .string "Unsorted array: "
11+
sorted: .string "Sorted array: "
12+
13+
.section .text
14+
.global main
15+
.extern printf
16+
17+
print_array:
18+
push r12
19+
push r13
20+
21+
mov r12, rdi # Loop variable
22+
lea r13, [rdi + 4*rsi] # Pointer after the last element
23+
24+
print_array_loop:
25+
cmp r12, r13 # If we're done iterating over the array then bail
26+
jge print_array_done
27+
mov rdi, OFFSET array_fmt # Otherwise print the current value
28+
mov esi, DWORD PTR [r12]
29+
xor rax, rax
30+
call printf
31+
lea r12, [r12 + 4] # And increment the loop variable pointer
32+
jmp print_array_loop
33+
34+
print_array_done:
35+
mov rdi, OFFSET lf # Print a closing newline
36+
xor rax, rax
37+
call printf
38+
39+
pop r13
40+
pop r12
41+
ret
42+
43+
bubble_sort:
44+
xor rcx, rcx # The outer loop counter
45+
lea rdx, [rdi + 4*rsi - 4] # The end address for the inner loop
46+
47+
outer_loop:
48+
cmp rcx, rsi # We first check if the outer loop is done
49+
jge bubble_sort_done # And if it is, return
50+
mov rax, rdi # Otherwise we initialize the loop variable of the inner loop
51+
inner_loop:
52+
mov r8d, DWORD PTR [rax] # Load array[j] and array[j+1] through a pointer
53+
mov r9d, DWORD PTR [rax + 4]
54+
cmp r8d, r9d # If array[j] <= array[j+1]
55+
jle loop_counters # Then we can skip this iteration
56+
mov DWORD PTR [rax], r9d # Otherwise swap the values
57+
mov DWORD PTR [rax + 4], r8d
58+
loop_counters:
59+
lea rax, [rax + 4] # First, advance the inner loop
60+
cmp rax, rdx
61+
jl inner_loop # And in case it's not done, repeat
62+
inc rcx # If it is done, go back to doing the outer loop
63+
jmp outer_loop
64+
65+
bubble_sort_done:
66+
ret
67+
68+
main:
69+
# Set up our stack
70+
sub rsp, 40
71+
72+
# We load the array in chunks onto the stack
73+
movaps xmm0, XMMWORD PTR [array]
74+
movaps XMMWORD PTR [rsp], xmm0
75+
movaps xmm0, XMMWORD PTR [array + 16]
76+
movaps XMMWORD PTR [rsp + 16], xmm0
77+
mov rax, QWORD PTR [array + 32]
78+
mov QWORD PTR [rsp + 32], rax
79+
80+
# Print the unsorted array
81+
mov rdi, OFFSET unsorted
82+
xor rax, rax
83+
call printf
84+
85+
mov rdi, rsp
86+
mov rsi, array_len
87+
call print_array
88+
89+
# Sort
90+
mov rdi, rsp
91+
mov rsi, array_len
92+
call bubble_sort
93+
94+
# Print the sorted array
95+
mov rdi, OFFSET sorted
96+
xor rax, rax
97+
call printf
98+
99+
mov rdi, rsp
100+
mov rsi, array_len
101+
call print_array
102+
103+
# Restore the stack pointer, set return value to 0
104+
add rsp, 40
105+
xor rax, rax
106+
ret

0 commit comments

Comments
 (0)