diff --git a/README.md b/README.md
index e5350d58c..c94eb2f3f 100644
--- a/README.md
+++ b/README.md
@@ -75,7 +75,7 @@ rely on CI.
 - [x] arm/aeabi_memset.S
 - [x] arm/aeabi_uidivmod.S
 - [x] arm/aeabi_uldivmod.S
-- [ ] arm/chkstk.S
+- [x] arm/chkstk.S
 - [ ] arm/divmodsi4.S (generic version is done)
 - [ ] arm/divsi3.S (generic version is done)
 - [ ] arm/modsi3.S (generic version is done)
diff --git a/compiler-builtins/src/arm.rs b/compiler-builtins/src/arm.rs
index 9e6608397..cfc0f1ab6 100644
--- a/compiler-builtins/src/arm.rs
+++ b/compiler-builtins/src/arm.rs
@@ -162,4 +162,25 @@ intrinsics! {
     pub unsafe extern "aapcs" fn __aeabi_memclr8(dest: *mut u8, n: usize) {
         __aeabi_memset4(dest, n, 0);
     }
+
+    // NOTE This function is implemented using assembly because they are using
+    // a custom calling convention
+    #[naked]
+    #[cfg(all(target_env = "msvc", not(feature = "no-asm")))]
+    pub unsafe extern "C" fn __chkstk() {
+        core::arch::naked_asm!(
+            ".p2align 2",
+            "lsl     r4,  r4, #2",
+            "mov     r12, sp",
+            "push {{ r5,  r6 }}",
+            "mov     r5,  r4",
+            "1:",
+            "sub     r12, r12, 4096",
+            "subs    r5,  r5,  4096",
+            "ldr     r6,  [r12]",
+            "bgt     1b",
+            "pop  {{ r5, r6 }}",
+            "bx      lr",
+        );
+    }
 }