Skip to content

Forward euler in x86_64 #503

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 16, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions contents/forward_euler_method/code/asm-x64/euler.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
.intel_syntax noprefix

.section .rodata
three: .double -3.0
fabs_const:
.long 4294967295
.long 2147483647
.long 0
.long 0
inital_val: .double 1.0
threshold: .double 0.01
timestep: .double 0.01
error_fmt: .string "%f %f\n"
fmt: .string "%d\n"

.section .text
.global main
.extern printf
.extern exp

# rdi - array size
# rsi - array ptr
# xmm0 - timestep
solve_euler:
movsd xmm1, inital_val
lea rax, [rsi + 8 * rdi + 8] # Set to end of the array
solve_euler_loop:
movsd xmm3, three # Set to -3.0
mulsd xmm2, xmm1 # xmm2 = -3.0 * array[i-1] * timestep
mulsd xmm2, xmm0
subsd xmm1, xmm2 # xmm1 = xmm1 - xmm2
movsd QWORD PTR [rsi], xmm1
add rsi, 8
cmp rsi, rax # Test if we have gone through the array
jne solve_euler_loop
solve_euler_return:
ret

# rdi - array size
# rsi - array ptr
# xmm0 - timestep
# xmm1 - threshold
# RET rax - success code 0 if sucess else 1
check_result:
push r12
push r13
xor rax, rax # Return code is 0
xor r12, r12 # The index is set to 0
mov r13, rdi # Moving array size to free rdi for printf
movsd xmm2, xmm0 # Moving timestep to free xmm0 for exp
jmp loop_check
results_loop:
cvtsi2sd xmm0, r12 # Making int to a double
movsd xmm3, three # Calculating exp(-3.0 * i * timestep)
mulsd xmm0, xmm3
mulsd xmm0, xmm2
call exp
movsd xmm3, QWORD PTR [rsi + r12 * 8] # Calculating abs(array[i] - xmm0)
subsd xmm2, xmm3
movq xmm3, fabs_const
andpd xmm0, xmm3
comisd xmm0, xmm1 # Check if abs(...) > threshold
jbe if_false
mov rdi, OFFSET error_fmt # If true print out array[i] and solution
mov rax, 1
call printf
mov rax, 1 # and set sucess code to failed (rax = 1)
if_false:
add r12, 1
loop_check:
cmp r12, r13 # Check if index is less the array size
jle results_loop
pop r13
pop r12
ret

main:
push rbp
sub rsp, 800 # Making double array[100]
mov rdi, 100
mov rsi, rsp
movsd xmm0, timestep
call solve_euler # Calling solve_euler
mov rdi, 100
mov rsi, rsp
movsd xmm0, timestep
movsd xmm1, threshold
call check_result # Check if results are correct
mov rdi, OFFSET fmt
mov rsi, rax
xor rax, rax
call printf # Print out success code
add rsp, 800 # Deallocating array
pop rbp
xor rax, rax
ret
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please insert a newline to avoid warnings


2 changes: 2 additions & 0 deletions contents/forward_euler_method/forward_euler_method.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ Full code for the visualization follows:
[import, lang:"fortran"](code/fortran/euler.f90)
{% sample lang="go" %}
[import, lang:"go"](code/golang/euler.go)
{% sample lang="asm-x64" %}
[import, lang:"asm-x64"](code/asm-x64/euler.s)
{% endmethod %}

<script>
Expand Down