mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 02:57:37 +00:00
remove allow_fail and uncomment the [feature(asm)] on every example
This commit is contained in:
parent
1ddddca57e
commit
fab2d46d24
@ -34,8 +34,8 @@ Inline assembly is currently supported on the following architectures:
|
||||
|
||||
Let us start with the simplest possible example:
|
||||
|
||||
```rust,allow_fail
|
||||
# #![feature(asm)]
|
||||
```rust
|
||||
#![feature(asm)]
|
||||
unsafe {
|
||||
asm!("nop");
|
||||
}
|
||||
@ -51,8 +51,8 @@ in the first argument of the `asm!` macro as a string literal.
|
||||
Now inserting an instruction that does nothing is rather boring. Let us do something that
|
||||
actually acts on data:
|
||||
|
||||
```rust,allow_fail
|
||||
# #![feature(asm)]
|
||||
```rust
|
||||
#![feature(asm)]
|
||||
let x: u64;
|
||||
unsafe {
|
||||
asm!("mov {}, 5", out(reg) x);
|
||||
@ -73,8 +73,8 @@ the template and will read the variable from there after the inline assembly fin
|
||||
|
||||
Let us see another example that also uses an input:
|
||||
|
||||
```rust,allow_fail
|
||||
# #![feature(asm)]
|
||||
```rust
|
||||
#![feature(asm)]
|
||||
let i: u64 = 3;
|
||||
let o: u64;
|
||||
unsafe {
|
||||
@ -113,8 +113,8 @@ readability, and allows reordering instructions without changing the argument or
|
||||
|
||||
We can further refine the above example to avoid the `mov` instruction:
|
||||
|
||||
```rust,allow_fail
|
||||
# #![feature(asm)]
|
||||
```rust
|
||||
#![feature(asm)]
|
||||
let mut x: u64 = 3;
|
||||
unsafe {
|
||||
asm!("add {0}, {number}", inout(reg) x, number = const 5);
|
||||
@ -127,8 +127,8 @@ This is different from specifying an input and output separately in that it is g
|
||||
|
||||
It is also possible to specify different variables for the input and output parts of an `inout` operand:
|
||||
|
||||
```rust,allow_fail
|
||||
# #![feature(asm)]
|
||||
```rust
|
||||
#![feature(asm)]
|
||||
let x: u64 = 3;
|
||||
let y: u64;
|
||||
unsafe {
|
||||
@ -149,8 +149,8 @@ There is also a `inlateout` variant of this specifier.
|
||||
|
||||
Here is an example where `inlateout` *cannot* be used:
|
||||
|
||||
```rust,allow_fail
|
||||
# #![feature(asm)]
|
||||
```rust
|
||||
#![feature(asm)]
|
||||
let mut a: u64 = 4;
|
||||
let b: u64 = 4;
|
||||
let c: u64 = 4;
|
||||
@ -170,8 +170,8 @@ Here the compiler is free to allocate the same register for inputs `b` and `c` s
|
||||
|
||||
However the following example can use `inlateout` since the output is only modified after all input registers have been read:
|
||||
|
||||
```rust,allow_fail
|
||||
# #![feature(asm)]
|
||||
```rust
|
||||
#![feature(asm)]
|
||||
let mut a: u64 = 4;
|
||||
let b: u64 = 4;
|
||||
unsafe {
|
||||
@ -189,8 +189,8 @@ Therefore, Rust inline assembly provides some more specific constraint specifier
|
||||
While `reg` is generally available on any architecture, these are highly architecture specific. E.g. for x86 the general purpose registers `eax`, `ebx`, `ecx`, `edx`, `ebp`, `esi`, and `edi`
|
||||
among others can be addressed by their name.
|
||||
|
||||
```rust,allow_fail,no_run
|
||||
# #![feature(asm)]
|
||||
```rust,no_run
|
||||
#![feature(asm)]
|
||||
let cmd = 0xd1;
|
||||
unsafe {
|
||||
asm!("out 0x64, eax", in("eax") cmd);
|
||||
@ -205,8 +205,8 @@ Note that unlike other operand types, explicit register operands cannot be used
|
||||
|
||||
Consider this example which uses the x86 `mul` instruction:
|
||||
|
||||
```rust,allow_fail
|
||||
# #![feature(asm)]
|
||||
```rust
|
||||
#![feature(asm)]
|
||||
fn mul(a: u64, b: u64) -> u128 {
|
||||
let lo: u64;
|
||||
let hi: u64;
|
||||
@ -241,8 +241,8 @@ This state is generally referred to as being "clobbered".
|
||||
We need to tell the compiler about this since it may need to save and restore this state
|
||||
around the inline assembly block.
|
||||
|
||||
```rust,allow_fail
|
||||
# #![feature(asm)]
|
||||
```rust
|
||||
#![feature(asm)]
|
||||
let ebx: u32;
|
||||
let ecx: u32;
|
||||
|
||||
@ -271,8 +271,8 @@ However we still need to tell the compiler that `eax` and `edx` have been modifi
|
||||
|
||||
This can also be used with a general register class (e.g. `reg`) to obtain a scratch register for use inside the asm code:
|
||||
|
||||
```rust,allow_fail
|
||||
# #![feature(asm)]
|
||||
```rust
|
||||
#![feature(asm)]
|
||||
// Multiply x by 6 using shifts and adds
|
||||
let mut x: u64 = 4;
|
||||
unsafe {
|
||||
@ -293,8 +293,8 @@ assert_eq!(x, 4 * 6);
|
||||
A special operand type, `sym`, allows you to use the symbol name of a `fn` or `static` in inline assembly code.
|
||||
This allows you to call a function or access a global variable without needing to keep its address in a register.
|
||||
|
||||
```rust,allow_fail
|
||||
# #![feature(asm)]
|
||||
```rust
|
||||
#![feature(asm)]
|
||||
extern "C" fn foo(arg: i32) {
|
||||
println!("arg = {}", arg);
|
||||
}
|
||||
@ -335,8 +335,8 @@ By default the compiler will always choose the name that refers to the full regi
|
||||
|
||||
This default can be overriden by using modifiers on the template string operands, just like you would with format strings:
|
||||
|
||||
```rust,allow_fail
|
||||
# #![feature(asm)]
|
||||
```rust
|
||||
#![feature(asm)]
|
||||
let mut x: u16 = 0xab;
|
||||
|
||||
unsafe {
|
||||
@ -360,7 +360,7 @@ You have to manually use the memory address syntax specified by the respectively
|
||||
For example, in x86/x86_64 and intel assembly syntax, you should wrap inputs/outputs in `[]`
|
||||
to indicate they are memory operands:
|
||||
|
||||
```rust,allow_fail
|
||||
```rust
|
||||
# #![feature(asm, llvm_asm)]
|
||||
# fn load_fpu_control_word(control: u16) {
|
||||
unsafe {
|
||||
@ -378,7 +378,7 @@ The compiler is allowed to instantiate multiple copies an `asm!` block, for exam
|
||||
|
||||
Moreover, due to [an llvm bug], you shouldn't use labels exclusively make of `0` and `1` digits, e.g. `0`, `11` or `101010`, as they may end up being interpreted as binary values.
|
||||
|
||||
```rust,allow_fail
|
||||
```rust
|
||||
#![feature(asm)]
|
||||
|
||||
let mut a = 0;
|
||||
@ -415,8 +415,8 @@ By default, an inline assembly block is treated the same way as an external FFI
|
||||
|
||||
Let's take our previous example of an `add` instruction:
|
||||
|
||||
```rust,allow_fail
|
||||
# #![feature(asm)]
|
||||
```rust
|
||||
#![feature(asm)]
|
||||
let mut a: u64 = 4;
|
||||
let b: u64 = 4;
|
||||
unsafe {
|
||||
|
Loading…
Reference in New Issue
Block a user