Skip to content

Commit 81021d7

Browse files
author
Julian
authored
Merge pull request #503 from Gathros/euler_asm
Forward euler in x86_64
2 parents a19f7ea + 2689bf7 commit 81021d7

File tree

2 files changed

+99
-0
lines changed

2 files changed

+99
-0
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
.intel_syntax noprefix
2+
3+
.section .rodata
4+
three: .double -3.0
5+
fabs_const:
6+
.long 4294967295
7+
.long 2147483647
8+
.long 0
9+
.long 0
10+
inital_val: .double 1.0
11+
threshold: .double 0.01
12+
timestep: .double 0.01
13+
error_fmt: .string "%f %f\n"
14+
fmt: .string "%d\n"
15+
16+
.section .text
17+
.global main
18+
.extern printf
19+
.extern exp
20+
21+
# rdi - array size
22+
# rsi - array ptr
23+
# xmm0 - timestep
24+
solve_euler:
25+
movsd xmm1, inital_val
26+
lea rax, [rsi + 8 * rdi + 8] # Set to end of the array
27+
solve_euler_loop:
28+
movsd xmm3, three # Set to -3.0
29+
mulsd xmm2, xmm1 # xmm2 = -3.0 * array[i-1] * timestep
30+
mulsd xmm2, xmm0
31+
subsd xmm1, xmm2 # xmm1 = xmm1 - xmm2
32+
movsd QWORD PTR [rsi], xmm1
33+
add rsi, 8
34+
cmp rsi, rax # Test if we have gone through the array
35+
jne solve_euler_loop
36+
solve_euler_return:
37+
ret
38+
39+
# rdi - array size
40+
# rsi - array ptr
41+
# xmm0 - timestep
42+
# xmm1 - threshold
43+
# RET rax - success code 0 if sucess else 1
44+
check_result:
45+
push r12
46+
push r13
47+
xor rax, rax # Return code is 0
48+
xor r12, r12 # The index is set to 0
49+
mov r13, rdi # Moving array size to free rdi for printf
50+
movsd xmm2, xmm0 # Moving timestep to free xmm0 for exp
51+
jmp loop_check
52+
results_loop:
53+
cvtsi2sd xmm0, r12 # Making int to a double
54+
movsd xmm3, three # Calculating exp(-3.0 * i * timestep)
55+
mulsd xmm0, xmm3
56+
mulsd xmm0, xmm2
57+
call exp
58+
movsd xmm3, QWORD PTR [rsi + r12 * 8] # Calculating abs(array[i] - xmm0)
59+
subsd xmm2, xmm3
60+
movq xmm3, fabs_const
61+
andpd xmm0, xmm3
62+
comisd xmm0, xmm1 # Check if abs(...) > threshold
63+
jbe if_false
64+
mov rdi, OFFSET error_fmt # If true print out array[i] and solution
65+
mov rax, 1
66+
call printf
67+
mov rax, 1 # and set sucess code to failed (rax = 1)
68+
if_false:
69+
add r12, 1
70+
loop_check:
71+
cmp r12, r13 # Check if index is less the array size
72+
jle results_loop
73+
pop r13
74+
pop r12
75+
ret
76+
77+
main:
78+
push rbp
79+
sub rsp, 800 # Making double array[100]
80+
mov rdi, 100
81+
mov rsi, rsp
82+
movsd xmm0, timestep
83+
call solve_euler # Calling solve_euler
84+
mov rdi, 100
85+
mov rsi, rsp
86+
movsd xmm0, timestep
87+
movsd xmm1, threshold
88+
call check_result # Check if results are correct
89+
mov rdi, OFFSET fmt
90+
mov rsi, rax
91+
xor rax, rax
92+
call printf # Print out success code
93+
add rsp, 800 # Deallocating array
94+
pop rbp
95+
xor rax, rax
96+
ret
97+

contents/forward_euler_method/forward_euler_method.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@ Full code for the visualization follows:
126126
[import, lang:"fortran"](code/fortran/euler.f90)
127127
{% sample lang="go" %}
128128
[import, lang:"go"](code/golang/euler.go)
129+
{% sample lang="asm-x64" %}
130+
[import, lang:"asm-x64"](code/asm-x64/euler.s)
129131
{% endmethod %}
130132

131133
<script>

0 commit comments

Comments
 (0)