diff --git a/hook_tests/backwards.asm b/hook_tests/backwards.asm
new file mode 100644
index 0000000..63b9a9c
--- /dev/null
+++ b/hook_tests/backwards.asm
@@ -0,0 +1,39 @@
+format ms64 coff
+
+section '.text' code readable executable
+
+use64
+
+public _loop
+_loop:
+ xor eax, eax
+ inc eax
+ mov rbx, rdx ; RDX is overwritten by mul
+@again:
+ cmp rbx, 0
+ je @loop_end
+ mul rcx
+ dec rbx
+ jmp @again
+@loop_end:
+ ret
+
+public _tail_recursion
+_tail_recursion:
+ test ecx, ecx
+ je @is_0
+ mov eax, ecx
+ dec ecx
+@loop:
+ test ecx, ecx
+ jz @tr_end
+
+ mul ecx
+ dec ecx
+
+ jnz @loop
+ jmp @tr_end
+@is_0:
+ mov eax, 1
+@tr_end:
+ ret
\ No newline at end of file
diff --git a/hook_tests/backwards.h b/hook_tests/backwards.h
new file mode 100644
index 0000000..683e046
--- /dev/null
+++ b/hook_tests/backwards.h
@@ -0,0 +1,17 @@
+#pragma once
+extern "C" {
+ /**
+ * Raises @num @cnt times
+ *
+ * @param num
+ * @param cnt
+ */
+ uint32_t _loop(uint32_t num, uint32_t cnt);
+
+ /**
+ * Computes factorial
+ *
+ * @param x
+ */
+ uint32_t _tail_recursion(uint32_t x);
+}
\ No newline at end of file
diff --git a/hook_tests/hook_tests.vcxproj b/hook_tests/hook_tests.vcxproj
index 6cb97a6..8632e04 100644
--- a/hook_tests/hook_tests.vcxproj
+++ b/hook_tests/hook_tests.vcxproj
@@ -147,6 +147,7 @@
+
@@ -155,11 +156,13 @@
+
+
diff --git a/hook_tests/hook_tests.vcxproj.filters b/hook_tests/hook_tests.vcxproj.filters
index eadae6b..b8c62d6 100644
--- a/hook_tests/hook_tests.vcxproj.filters
+++ b/hook_tests/hook_tests.vcxproj.filters
@@ -24,6 +24,9 @@
Header Files
+
+ Header Files
+
@@ -38,9 +41,13 @@
Source Files
+
+ Source Files
+
+
\ No newline at end of file
diff --git a/hook_tests/main.cpp b/hook_tests/main.cpp
index 335b2a9..19fe2dc 100644
--- a/hook_tests/main.cpp
+++ b/hook_tests/main.cpp
@@ -5,6 +5,7 @@
#include "catch.hpp"
#include "simple_tests.h"
#include "advanced_instructions.h"
+#include "backwards.h"
TEST_CASE("Simple functions work as expected, unhooked") {
REQUIRE(_small() == 0);
@@ -24,4 +25,16 @@ TEST_CASE("Advanced instruction functions work as expected, unhokked") {
REQUIRE((result[1] - result[2]) < DBL_EPSILON);
REQUIRE((result[2] - result[3]) < DBL_EPSILON);
REQUIRE((result[0] - 3.) < DBL_EPSILON);
+}
+
+TEST_CASE("Loops & tail recursion work as expected, unhook") {
+ REQUIRE(_loop(2, 3) == 8);
+ REQUIRE(_loop(5, 3) == 125);
+ REQUIRE(_loop(5, 0) == 1);
+ REQUIRE(_loop(5, 1) == 5);
+
+ REQUIRE(_tail_recursion(0) == 1);
+ REQUIRE(_tail_recursion(1) == 1);
+ REQUIRE(_tail_recursion(2) == 2);
+ REQUIRE(_tail_recursion(5) == 120);
}
\ No newline at end of file