diff --git a/src/kernel_internals/typing/asm_contracts.ml b/src/kernel_internals/typing/asm_contracts.ml
index 0d644c1604bca7cbcd6c9884a42c841783aaff8d..7814244c441c49544c5f306d25c8831af18fcef0 100644
--- a/src/kernel_internals/typing/asm_contracts.ml
+++ b/src/kernel_internals/typing/asm_contracts.ml
@@ -168,6 +168,24 @@ class visit_assembly =
                (fun x -> (to_id_term x, From (List.map to_id_from lv_from)))
                lv_out)
         in
+        let mk_initialized x =
+          let typ = Cil.typeOfTermLval x in
+          if Logic_utils.isLogicVoidType typ then None
+          else begin
+            let t = Logic_utils.mk_logic_AddrOf ~loc x typ in
+            let pred =
+              Logic_const.(
+                new_predicate
+                  (pinitialized ~loc (here_label,t)))
+            in
+            Some (Normal, pred)
+          end
+        in
+        let initialized () =
+          if Kernel.AsmContractsInitialized.get() then begin
+            List.filter_map mk_initialized lv_out
+          end else []
+        in
         let filter ca =
           match ca.annot_content with
           (* search for a statement contract that applies to all cases. *)
@@ -178,7 +196,8 @@ class visit_assembly =
         (match contracts with
          | [] ->
            let assigns = assigns () in
-           let bhv = Cil.mk_behavior ~assigns () in
+           let post_cond = initialized () in
+           let bhv = Cil.mk_behavior ~assigns ~post_cond () in
            let spec = Cil.empty_funspec () in
            spec.spec_behavior <- [ bhv ];
            let ca =
@@ -192,10 +211,12 @@ class visit_assembly =
                Property.ip_assigns_of_behavior kf (Kstmt stmt) ~active bhv in
              let ip_from =
                Property.ip_from_of_behavior kf (Kstmt stmt) ~active bhv in
+             let ip_init =
+               Property.ip_ensures_of_behavior kf (Kstmt stmt) bhv
+             in
              List.iter
-               Property_status.(
-                 fun x -> emit emitter ~hyps:[] x True)
-               (Option.to_list ip_assigns @ ip_from)
+               Property_status.(fun x -> emit emitter ~hyps:[] x True)
+               (Option.to_list ip_assigns @ ip_from @ ip_init)
            end
          | [ { annot_content = AStmtSpec ([], spec) } ] ->
            (* Already existing contracts. Just add assigns clause for
@@ -236,6 +257,8 @@ let transform file =
 let () =
   File.add_code_transformation_after_cleanup
     ~deps:[(module Kernel.AsmContractsGenerate);
+           (module Kernel.AsmContractsInitialized);
            (module Kernel.AsmContractsAutoValidate) ]
+    ~before:[Inline_stmt_contracts.category]
     category
     transform
diff --git a/src/kernel_services/ast_transformations/inline_stmt_contracts.ml b/src/kernel_services/ast_transformations/inline_stmt_contracts.ml
new file mode 100644
index 0000000000000000000000000000000000000000..710fe1051385b63769a000dea1fac068a0ffa118
--- /dev/null
+++ b/src/kernel_services/ast_transformations/inline_stmt_contracts.ml
@@ -0,0 +1,156 @@
+(**************************************************************************)
+(*                                                                        *)
+(*  This file is part of Frama-C.                                         *)
+(*                                                                        *)
+(*  Copyright (C) 2007-2024                                               *)
+(*    CEA (Commissariat à l'énergie atomique et aux énergies              *)
+(*         alternatives)                                                  *)
+(*                                                                        *)
+(*  you can redistribute it and/or modify it under the terms of the GNU   *)
+(*  Lesser General Public License as published by the Free Software       *)
+(*  Foundation, version 2.1.                                              *)
+(*                                                                        *)
+(*  It is distributed in the hope that it will be useful,                 *)
+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)
+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *)
+(*  GNU Lesser General Public License for more details.                   *)
+(*                                                                        *)
+(*  See the GNU Lesser General Public License version 2.1                 *)
+(*  for more details (enclosed in the file licenses/LGPLv2.1).            *)
+(*                                                                        *)
+(**************************************************************************)
+
+open Cil_types
+
+let emitter =
+  let open Emitter in
+  create
+    "inline_stmt_contract" [Code_annot; Property_status]
+    ~correctness:[] ~tuning:[]
+
+let category = File.register_code_transformation_category "inline_stmt_contract"
+
+let fresh_pred p =
+  let v = new Visitor.frama_c_refresh (Project.current()) in
+  Visitor.visitFramacPredicate v p
+
+let nb_labels = ref 0
+
+let new_label () =
+  let res = Printf.sprintf "__fc_inline_contract_label_%d" !nb_labels in
+  incr nb_labels; res
+
+let propagate_status p1 p2 =
+  match Property_status.get p1 with
+  | Best (True, _) -> Property_status.emit emitter ~hyps:[p1] p2 True
+  | _ ->
+    begin
+      let open Property_status in
+      let propagate_status_p1 e p s =
+        if Property.equal p p1 && s = True
+           && not (Emitter.(Usable_emitter.equal e.emitter (get emitter)))
+        then
+          Property_status.emit emitter ~hyps:[p1] p2 True
+      in
+      Property_status.register_status_update_hook propagate_status_p1;
+      let propagate_status_assertion e p s =
+        if Property.equal p p2 && s = Property_status.True
+           && not (Emitter.(Usable_emitter.equal e.emitter (get emitter)))
+        then
+          Property_status.emit emitter ~hyps:[p2] p1 True
+      in
+      Property_status.register_status_update_hook propagate_status_assertion
+    end
+
+let treat_behavior for_list kf stmt acc b =
+  let loc = Cil_datatype.Stmt.loc stmt in
+  let pand p1 p2 = Logic_const.pand ~loc (p1,p2.ip_content.tp_statement) in
+  let assumes = List.fold_left pand Logic_const.ptrue b.b_assumes in
+  let mk_annot p =
+    let p = fresh_pred p in
+    let p = Logic_const.toplevel_predicate p in
+    Logic_const.new_code_annotation (AAssert (for_list,p))
+  in
+  let add_assert req =
+    let p = Logic_const.pimplies ~loc (assumes, req.ip_content.tp_statement) in
+    let ip_req = Property.ip_of_requires kf (Kstmt stmt) b req in
+    let annot = mk_annot p in
+    Annotations.add_code_annot emitter stmt annot;
+    let ip_annot = Property.ip_of_code_annot_single kf stmt annot in
+    propagate_status ip_req ip_annot
+  in
+  let treat_post_cond acc (k,p as postcond) =
+    match k with
+    | Normal ->
+      if Logic_utils.is_trivially_true assumes then begin
+        (b, postcond, mk_annot p.ip_content.tp_statement) :: acc
+      end else begin
+        (match List.filter (fun l -> not (Cil.is_case_label l)) stmt.labels with
+         | [] -> stmt.labels <- Label (new_label(),loc,false) :: stmt.labels
+         | _ -> ());
+        let p =
+          Logic_const.(
+            pimplies ~loc
+              (pat ~loc (assumes,StmtLabel (ref stmt)),
+               p.ip_content.tp_statement))
+        in
+        (b, postcond, mk_annot p) :: acc
+      end
+    | _ -> acc
+  in
+  List.iter add_assert b.b_requires;
+  List.fold_left treat_post_cond acc b.b_post_cond
+
+let add_one_postcond kf orig_stmt new_stmt (b, post, assertion) =
+  Annotations.add_code_annot emitter ~kf new_stmt assertion;
+  let post = Property.ip_of_ensures kf (Kstmt orig_stmt) b post in
+  let assertion = Property.ip_of_code_annot_single kf new_stmt assertion in
+  propagate_status post assertion
+
+class inline_stmt_contract =
+  object(self)
+    inherit Visitor.frama_c_inplace
+    method! vstmt_aux s =
+      let loc = Cil_datatype.Stmt.loc s in
+      let kf = Option.get self#current_kf in
+      match Annotations.code_annot ~filter:Logic_utils.is_contract s with
+      | [ { annot_content = AStmtSpec (l,spec) } ] ->
+        let bhvs = spec.spec_behavior in
+        let posts = List.fold_left (treat_behavior l kf s) [] bhvs in
+        (match posts with
+         | [] -> Cil.DoChildren
+         | _ ->
+           let nop = Cil.mkStmtOneInstr ~valid_sid:true (Skip loc) in
+           List.iter (add_one_postcond kf s nop) posts;
+           let b = Cil.mkBlockNonScoping [s; nop] in
+           let b = Cil.transient_block b in
+           let res = Cil.mkStmt ~valid_sid:true (Block b) in
+           Ast.mark_as_grown ();
+           File.must_recompute_cfg (Option.get self#current_func);
+           ChangeTo res
+        )
+      | [ _ ] -> Kernel.fatal "code annotation was expected to be a contract"
+      | _ :: _ -> Kernel.fatal "a statement can only have one contract"
+      | [] -> Cil.DoChildren
+
+    method! vfunc _ = nb_labels:= 0; Cil.DoChildren
+
+    method! vexpr _ = Cil.SkipChildren
+    method! vlval _ = Cil.SkipChildren
+    method! vtype _ = Cil.SkipChildren
+    method! vspec _ = Cil.SkipChildren
+    method! vcode_annot _ = Cil.SkipChildren
+    method! vinst _ = Cil.SkipChildren
+
+  end
+
+let inline_stmt_contract ast =
+  if Kernel.InlineStmtContracts.get () then
+    begin
+      let vis = new inline_stmt_contract in
+      Visitor.visitFramacFileSameGlobals vis ast
+    end
+
+let () =
+  let deps = [ (module Kernel.InlineStmtContracts: Parameter_sig.S) ] in
+  File.add_code_transformation_after_cleanup ~deps category inline_stmt_contract
diff --git a/src/kernel_services/ast_transformations/inline_stmt_contracts.mli b/src/kernel_services/ast_transformations/inline_stmt_contracts.mli
new file mode 100644
index 0000000000000000000000000000000000000000..5bb3bdd9fa4fc3ecb2288e18abf275ea4bb12d3b
--- /dev/null
+++ b/src/kernel_services/ast_transformations/inline_stmt_contracts.mli
@@ -0,0 +1,28 @@
+(**************************************************************************)
+(*                                                                        *)
+(*  This file is part of Frama-C.                                         *)
+(*                                                                        *)
+(*  Copyright (C) 2007-2024                                               *)
+(*    CEA (Commissariat à l'énergie atomique et aux énergies              *)
+(*         alternatives)                                                  *)
+(*                                                                        *)
+(*  you can redistribute it and/or modify it under the terms of the GNU   *)
+(*  Lesser General Public License as published by the Free Software       *)
+(*  Foundation, version 2.1.                                              *)
+(*                                                                        *)
+(*  It is distributed in the hope that it will be useful,                 *)
+(*  but WITHOUT ANY WARRANTY; without even the implied warranty of        *)
+(*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *)
+(*  GNU Lesser General Public License for more details.                   *)
+(*                                                                        *)
+(*  See the GNU Lesser General Public License version 2.1                 *)
+(*  for more details (enclosed in the file licenses/LGPLv2.1).            *)
+(*                                                                        *)
+(**************************************************************************)
+
+(** transforms requires and ensures of statement contracts into assert.
+    This transformation is done after cleanup
+*)
+
+val emitter : Emitter.t
+val category : File.code_transformation_category
diff --git a/src/kernel_services/plugin_entry_points/kernel.ml b/src/kernel_services/plugin_entry_points/kernel.ml
index 4efe6d0b8ea0372cef138879add02e3d15026285..e704803c577786149f2a0174d9f55535a104dc1b 100644
--- a/src/kernel_services/plugin_entry_points/kernel.ml
+++ b/src/kernel_services/plugin_entry_points/kernel.ml
@@ -1358,6 +1358,17 @@ module AsmContractsGenerate =
                   to gcc's extended syntax"
     end)
 
+let () = Parameter_customize.set_group normalisation
+module AsmContractsInitialized =
+  False
+    (struct
+      let option_name = "-asm-contracts-ensure-init"
+      let module_name = "AsmContractsInitialized"
+      let help = "when contracts for assembly code are generated, add \
+                  postconditions stating that the output are initialized."
+    end)
+
+
 let () = Parameter_customize.set_group normalisation
 module AsmContractsAutoValidate =
   False
@@ -1368,6 +1379,17 @@ module AsmContractsAutoValidate =
                   (defaults to false)"
     end)
 
+let () = Parameter_customize.set_group normalisation
+module InlineStmtContracts =
+  False
+    (struct
+      let option_name = "-inline-stmt-contracts"
+      let module_name = "InlineStmtContracts"
+      let help = "transforms requires/ensures clauses of statement contracts \
+                  into plain assertions, enabling their verification \
+                  by plug-ins with incomplete support for statement contracts."
+    end)
+
 let () = Parameter_customize.set_group normalisation
 module RemoveExn =
   False
diff --git a/src/kernel_services/plugin_entry_points/kernel.mli b/src/kernel_services/plugin_entry_points/kernel.mli
index 952d796c3e825e0ac777949d7383b19693174995..8472baa286db098f13eb54ced7bb331744d3f3e5 100644
--- a/src/kernel_services/plugin_entry_points/kernel.mli
+++ b/src/kernel_services/plugin_entry_points/kernel.mli
@@ -537,8 +537,14 @@ module AggressiveMerging: Parameter_sig.Bool
 module AsmContractsGenerate: Parameter_sig.Bool
 (** Behavior of option "-asm-contracts" *)
 
+module AsmContractsInitialized: Parameter_sig.Bool
+(** Behavior of option "-asm-contracts-ensure-init" *)
+
 module AsmContractsAutoValidate: Parameter_sig.Bool
-(** Behavior of option "-asm-contracts-auto-validate." *)
+(** Behavior of option "-asm-contracts-auto-validate" *)
+
+module InlineStmtContracts: Parameter_sig.Bool
+(** Behavior of option "-inline-stmt-contracts" *)
 
 module RemoveExn: Parameter_sig.Bool
 (** Behavior of option "-remove-exn" *)
diff --git a/tests/misc/asm_initialized.i b/tests/misc/asm_initialized.i
new file mode 100644
index 0000000000000000000000000000000000000000..b0b3d60f4f4820d1157edd9136bf1c29fd26520e
--- /dev/null
+++ b/tests/misc/asm_initialized.i
@@ -0,0 +1,12 @@
+/* run.config*
+PLUGIN: @EVA_PLUGINS@ report
+STDOPT: #"-asm-contracts-ensure-init -asm-contracts-auto-validate -inline-stmt-contracts -absolute-valid-range 0x10000000-0xf00000000 -print -report"
+*/
+
+int main() {
+  int* sp;
+  int x = 2;
+  asm volatile ("mov %%rsp, %0;":"=r"(sp));
+  *(sp - 2) = 3;
+  return x;
+}
diff --git a/tests/misc/oracle/asm_initialized.res.oracle b/tests/misc/oracle/asm_initialized.res.oracle
new file mode 100644
index 0000000000000000000000000000000000000000..2d450df9513cfe5447010f99a6c95454dfd27dd3
--- /dev/null
+++ b/tests/misc/oracle/asm_initialized.res.oracle
@@ -0,0 +1,70 @@
+[kernel] Parsing asm_initialized.i (no preprocessing)
+[eva] Analyzing a complete application starting at main
+[eva] Computing initial state
+[eva] Initial state computed
+[eva:initial-state] Values of globals at initialization
+  NULL[rbits 2147483648 to 515396075527] ∈ [--..--]
+[eva:alarm] asm_initialized.i:9: Warning: 
+  assertion 'inline_stmt_contract' got status unknown.
+[eva:alarm] asm_initialized.i:10: Warning: 
+  out of bounds write. assert \valid(sp - 2);
+[eva] Recording results for main
+[eva] Done for function main
+[eva] ====== VALUES COMPUTED ======
+[eva:final-states] Values at end of function main:
+  NULL[rbits 2147483648 to 515396075527] ∈ [--..--]
+  x ∈ {2}
+[from] Computing for function main
+[from] Done for function main
+[from] ====== DEPENDENCIES COMPUTED ======
+  These dependencies hold at termination for the executions that terminate:
+[from] Function main:
+  NULL[268435456..4294967298] FROM \nothing (and SELF)
+  \result FROM \nothing
+[from] ====== END OF DEPENDENCIES ======
+[inout] Out (internal) for function main:
+    NULL[268435456..4294967298]; x
+[inout] Inputs for function main:
+    \nothing
+[report] Computing properties status...
+
+--------------------------------------------------------------------------------
+--- Properties of Function 'main'
+--------------------------------------------------------------------------------
+
+[  Valid  ] Post-condition (file asm_initialized.i, line 9) at assembly (file asm_initialized.i, line 9)
+            by asm_contracts.
+[  Valid  ] Assigns (file asm_initialized.i, line 9) at assembly (file asm_initialized.i, line 9)
+            by asm_contracts.
+[  Valid  ] Assertion 'inline_stmt_contract' (file asm_initialized.i, line 9)
+            by inline_stmt_contract.
+[    -    ] Assertion 'Eva,mem_access' (file asm_initialized.i, line 10)
+            tried with Eva.
+[  Valid  ] Froms (file asm_initialized.i, line 9) at assembly (file asm_initialized.i, line 9)
+            by asm_contracts.
+[  Valid  ] Default behavior at assembly (file asm_initialized.i, line 9)
+            by Frama-C kernel.
+
+--------------------------------------------------------------------------------
+--- Status Report Summary
+--------------------------------------------------------------------------------
+     5 Completely validated
+     1 To be validated
+     6 Total
+--------------------------------------------------------------------------------
+/* Generated by Frama-C */
+int main(void)
+{
+  int *sp;
+  int x = 2;
+  /*@ ensures \initialized(&sp);
+      assigns sp;
+      assigns sp \from \nothing; */
+  __asm__ volatile ("mov %%rsp, %0;" : "=r" (sp));
+  /*@ assert inline_stmt_contract: \initialized(&sp); */ ;
+  /*@ assert Eva: mem_access: \valid(sp - 2); */
+  *(sp - 2) = 3;
+  return x;
+}
+
+
diff --git a/tests/syntax/inline_stmt_contract.i b/tests/syntax/inline_stmt_contract.i
new file mode 100644
index 0000000000000000000000000000000000000000..551a6c461a02df52d91495bef90d65cbd08fded5
--- /dev/null
+++ b/tests/syntax/inline_stmt_contract.i
@@ -0,0 +1,44 @@
+/* run.config
+OPT: -inline-stmt-contracts -print
+*/
+
+int X;
+
+int f() {
+  /*@ requires X == 0;
+      ensures X == 1;
+  */
+  X++;
+  return X;
+}
+
+int g() {
+
+  /*@ behavior b:
+        assumes X >= 0;
+        requires X > -1;
+        ensures X == 0;
+   */
+  if (X >= 0) { X = 0; } else { X = -1; }
+  return X;
+}
+
+int h() {
+  /*@ ensures \false; */
+  return 1;
+}
+
+int i() {
+  /*@ behavior b0:
+        assumes X == 0;
+        ensures X == 1;
+  */
+  X++;
+
+  /*@ behavior b1:
+        assumes X == 1;
+        ensures X == 2;
+  */
+  X++;
+  return X;
+}
diff --git a/tests/syntax/oracle/inline_stmt_contract.res.oracle b/tests/syntax/oracle/inline_stmt_contract.res.oracle
new file mode 100644
index 0000000000000000000000000000000000000000..39a85c89c69eb63d2706ff0eeb968d2a5ee50f8c
--- /dev/null
+++ b/tests/syntax/oracle/inline_stmt_contract.res.oracle
@@ -0,0 +1,68 @@
+[kernel] Parsing inline_stmt_contract.i (no preprocessing)
+/* Generated by Frama-C */
+int X;
+int f(void)
+{
+  /*@ assert inline_stmt_contract: X ≡ 0; */
+  /*@ requires X ≡ 0;
+      ensures X ≡ 1; */
+  X ++;
+  /*@ assert inline_stmt_contract: X ≡ 1; */ ;
+  return X;
+}
+
+int g(void)
+{
+  __fc_inline_contract_label_0:
+  /*@ assert inline_stmt_contract: X ≥ 0 ⇒ X > -1; */
+  /*@ behavior b:
+        assumes X ≥ 0;
+        requires X > -1;
+        ensures X ≡ 0; */
+  if (X >= 0) X = 0; else X = -1;
+  /*@
+  assert
+  inline_stmt_contract: \at(X ≥ 0,__fc_inline_contract_label_0) ⇒ X ≡ 0;
+   */
+  ;
+  return X;
+}
+
+int h(void)
+{
+  int __retres;
+  /*@ ensures \false; */
+  {
+    __retres = 1;
+    goto return_label;
+  }
+  /*@ assert inline_stmt_contract: \false; */ ;
+  return_label: return __retres;
+}
+
+int i(void)
+{
+  __fc_inline_contract_label_0:
+  /*@ behavior b0:
+        assumes X ≡ 0;
+        ensures X ≡ 1; */
+  X ++;
+  /*@
+  assert
+  inline_stmt_contract: \at(X ≡ 0,__fc_inline_contract_label_0) ⇒ X ≡ 1;
+   */
+  ;
+  __fc_inline_contract_label_1:
+  /*@ behavior b1:
+        assumes X ≡ 1;
+        ensures X ≡ 2; */
+  X ++;
+  /*@
+  assert
+  inline_stmt_contract: \at(X ≡ 1,__fc_inline_contract_label_1) ⇒ X ≡ 2;
+   */
+  ;
+  return X;
+}
+
+