|
| 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 | + |
0 commit comments