You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
With the `asm!` macro, the assembly code is emitted in a function scope and integrated into the compiler-generated assembly code of a function.
76
78
This assembly code must obey [strict rules](#rules-for-inline-assembly) to avoid undefined behavior.
77
79
Note that in some cases the compiler may choose to emit the assembly code as a separate function and generate a call to it.
78
80
81
+
r[asm.scope.naked_asm]
82
+
With the `naked_asm!` macro, the assembly code is emitted in a function scope and constitutes the full assembly code of a function.
83
+
The `naked_asm!` macro is only allowed in [naked functions](../attributes/codegen.md#the-naked-attribute).
84
+
79
85
r[asm.scope.global_asm]
80
86
With the `global_asm!` macro, the assembly code is emitted in a global scope, outside a function.
81
87
This can be used to hand-write entire functions using assembly code, and generally provides much more freedom to use arbitrary registers and assembler directives.
@@ -185,8 +191,11 @@ Operand expressions are evaluated from left to right, just like function call ar
185
191
After the `asm!` has executed, outputs are written to in left to right order.
186
192
This is significant if two outputs point to the same place: that place will contain the value of the rightmost output.
187
193
194
+
r[asm.operand-type.naked_asm-restriction]
195
+
Because `naked_asm!` defines a whole function body, it can only use `sym` and `const` operands.
196
+
188
197
r[asm.operand-type.global_asm-restriction]
189
-
Since`global_asm!` exists outside a function, it can only use `sym` and `const` operands.
198
+
Because`global_asm!` exists outside a function, it can only use `sym` and `const` operands.
190
199
191
200
## Register operands
192
201
@@ -578,9 +587,13 @@ r[asm.options.checks.pure]
578
587
r[asm.options.checks.noreturn]
579
588
- It is a compile-time error to specify `noreturn` on an asm block with outputs.
580
589
590
+
r[asm.options.naked_asm-restriction]
591
+
`global_asm!` only supports the `att_syntax` and `raw` options.
592
+
The remaining options are not meaningful because the inline assembly defines the whole function body.
593
+
581
594
r[asm.options.global_asm-restriction]
582
595
`global_asm!` only supports the `att_syntax` and `raw` options.
583
-
The remaining options are not meaningful for global-scope inline assembly
596
+
The remaining options are not meaningful for global-scope inline assembly.
> **Note**: As a general rule, the flags covered by `preserves_flags` are those which are *not* preserved when performing a function call.
695
708
709
+
## Rules for naked inline assembly
710
+
711
+
r[asm.naked-rules]
712
+
713
+
r[asm.naked-rules.intro]
714
+
To avoid undefined behavior, these rules must be followed when using function-scope inline assembly in naked functions (`naked_asm!`):
715
+
716
+
r[asm.naked-rules.reg-not-input]
717
+
- Any registers not used for function inputs according to the calling convention and function signature will contain an undefined value on entry to the asm block.
718
+
- An "undefined value" in the context of inline assembly means that the register can (non-deterministically) have any one of the possible values allowed by the architecture.
719
+
Notably it is not the same as an LLVM `undef` which can have a different value every time you read it (since such a concept does not exist in assembly code).
720
+
721
+
r[asm.naked-rules.reg-not-output]
722
+
- Any callee-saved registers must have the same value upon exiting the asm block as they had on entry, otherwise behavior is undefined.
723
+
- Caller-saved registes may be used freely, even if they are not used for the return value.
724
+
725
+
r[asm.naked-rules.unwind]
726
+
- Behavior is undefined if execution unwinds out of an asm block.
727
+
- This also applies if the assembly code calls a function which then unwinds.
728
+
729
+
r[asm.naked-rules.noreturn]
730
+
- Behavior is undefined if execution falls through to the end of the asm block.
731
+
732
+
r[asm.naked-rules.mem-same-as-ffi]
733
+
- The set of memory locations that assembly code is allowed to read and write are the same as those allowed for an FFI function.
734
+
- Refer to the unsafe code guidelines for the exact rules.
735
+
- These rules do not apply to memory which is private to the asm code, such as stack space allocated within the asm block.
736
+
737
+
r[asm.naked-rules.black-box]
738
+
- The compiler cannot assume that the instructions in the asm are the ones that will actually end up executed.
739
+
- This effectively means that the compiler must treat the `naked_asm!` as a black box and only take the interface specification into account, not the instructions themselves.
740
+
- Runtime code patching is allowed, via target-specific mechanisms.
741
+
- However there is no guarantee that each `naked_asm!` directly corresponds to a single instance of instructions in the object file: the compiler is free to duplicate or deduplicate `naked_asm!` blocks.
742
+
743
+
r[asm.naked-rules.not-exactly-once]
744
+
- You cannot assume that an `naked_asm!` block will appear exactly once in the output binary.
745
+
The compiler is allowed to instantiate multiple copies of the `naked_asm!` block, for example when the function containing it is inlined in multiple places.
0 commit comments