diff --git a/gprof/Makefile b/gprof/Makefile
new file mode 100644
index 0000000..f06abee
--- /dev/null
+++ b/gprof/Makefile
@@ -0,0 +1,17 @@
+export CFLAGS = -pg # Use gprof
+export CFLAGS += -static # Static link
+export CFLAGS += -O0 # Heavy optimization
+export CFLAGS += -Wl,--defsym,_mcount=mcount # Link _mcount to mcount
+export CFLAGS += -mapcs-frame # Use standard calling convention
+#export CFLAGS += -fno-omit-frame-pointer # Don't omit fp (might not necessary to enable this)
+
+AppMain.exe:
+ @arm-mingw32ce-gcc -o AppMain $(CFLAGS) profile.c
+
+AppMain.mitigated.s:
+ @arm-mingw32ce-gcc -O0 -S -fno-omit-frame-pointer -mapcs-frame profile.c
+ @mv profile.s AppMain.mitigated.s
+
+.PHONY:
+clean:
+ @rm -f AppMain.exe AppMain*.s
diff --git a/gprof/README.md b/gprof/README.md
new file mode 100644
index 0000000..0626aad
--- /dev/null
+++ b/gprof/README.md
@@ -0,0 +1,29 @@
+Gprof test program
+------------------
+
+ - Needs gprof-enabled CeGCC.
+ - `make` to compile AppMain.exe.
+
+
+## CFLAGS
+
+By default, GCC emits code that is not comformant to [APCS](https://www.cl.cam.ac.uk/~fms27/teaching/2001-02/arm-project/02-sort/apcs.txt).
+Gprof's `_mcount` assumes APCS-compliant and `fp` being present in the binary.
+
+- `-mapcs-frame` is disabled by default for all optimization level
+ - It leads to a crash without APCS. Must be enabled explicitly.
+- `-fno-omit-frame-pointer` is enabled for all optimization level but `-O0`
+ - It might have some effect on the compilation, but not sure
+ - As I experiment unsetting (disabling) this flag, it doesn't crash even with `-O2`
+
+
+## Experiment results: flags' effect
+
+- `-fno-omit-frame-pointer` looks like it has nothing to do with calling convention because of `-mapcs-frame`
+- Optimization other than `-O0` optimizes the func call (inlining etc) and the resulting graph becomes strange (lack of main() etc.)
+
+
+|CFLAGS|Screenshot|
+|:-----|:--------:|
+|`-O0`|
|
+|`-O2`|
|
diff --git a/gprof/o0.png b/gprof/o0.png
new file mode 100644
index 0000000..a121a65
Binary files /dev/null and b/gprof/o0.png differ
diff --git a/gprof/o2.png b/gprof/o2.png
new file mode 100644
index 0000000..55c503d
Binary files /dev/null and b/gprof/o2.png differ
diff --git a/gprof/profile.c b/gprof/profile.c
new file mode 100644
index 0000000..797f1df
--- /dev/null
+++ b/gprof/profile.c
@@ -0,0 +1,31 @@
+#include
+
+int __attribute__((noinline)) fibonacci(int n) {
+ if (n <= 1) return n;
+ return fibonacci(n - 1) + fibonacci(n - 2);
+}
+
+void __attribute__((noinline)) dummy_work(int count) {
+ volatile int sum = 0;
+ for (int i = 0; i < count; i++) {
+ sum += i;
+ }
+}
+
+void __attribute__((noinline)) heavy_logic() {
+ for (int i = 0; i < 5; i++) {
+ // It will take up to a few sec
+ printf("Computing fib(30)... iteration %d\n", i);
+ fibonacci(30);
+ }
+}
+
+int main(int argc, char* argv[]) {
+ printf("--- Profiling Test Start ---\n");
+
+ heavy_logic();
+ dummy_work(1000);
+
+ printf("--- Profiling Test End ---\n");
+ return 0;
+}