Skip to content

Commit e5fe9eb

Browse files
author
Timothée Delabrouille
committed
New 'Label' section with example and explainations
1 parent 69e1d22 commit e5fe9eb

File tree

1 file changed

+37
-3
lines changed
  • src/doc/unstable-book/src/library-features

1 file changed

+37
-3
lines changed

src/doc/unstable-book/src/library-features/asm.md

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,43 @@ unsafe {
372372
# }
373373
```
374374

375+
## Labels
376+
377+
The compiler is allowed to instantiate multiple copies an `asm!` block, for example when the function containing it is inlined in multiple places. As a consequence, you should only use GNU assembler [local labels] inside inline assembly code. Defining symbols in assembly code may lead to assembler and/or linker errors due to duplicate symbol definitions.
378+
379+
Moreover due to [a llvm bug], you cannot use `0` or `1` as labels. Therefore only labels in the `2`-`99` range are allowed.
380+
381+
```rust
382+
#![feature(asm)]
383+
384+
let mut a = 0;
385+
unsafe {
386+
asm!(
387+
"mov {0}, 10",
388+
"2:",
389+
"sub {0}, 1",
390+
"cmp {0}, 3",
391+
"jle 2f",
392+
"jmp 2b",
393+
"2:",
394+
"add {0}, 2",
395+
out(reg) a
396+
);
397+
}
398+
assert_eq!(a, 5);
399+
```
400+
401+
This will decrement the `{0}` register value from 10 to 3, then add 2 and store it in `a`.
402+
403+
This example show a few thing:
404+
405+
First that the same number can be used as a label multiple times in the same inline block.
406+
407+
Second, that when a numeric label is used as a reference (as an instruction operand, for example), the suffixes b (“backward”) or f (“forward”) should be added to the numeric label. It will then refer to the nearest label defined by this number in this direction.
408+
409+
[local labels]: https://sourceware.org/binutils/docs/as/Symbol-Names.html#Local-Labels
410+
[a llvm bug]: https://bugs.llvm.org/show_bug.cgi?id=36144
411+
375412
## Options
376413

377414
By default, an inline assembly block is treated the same way as an external FFI function call with a custom calling convention: it may read/write memory, have observable side effects, etc. However in many cases, it is desirable to give the compiler more information about what the assembly code is actually doing so that it can optimize better.
@@ -787,8 +824,5 @@ The compiler performs some additional checks on options:
787824
- You are responsible for switching any target-specific state (e.g. thread-local storage, stack bounds).
788825
- The set of memory locations that you may access is the intersection of those allowed by the `asm!` blocks you entered and exited.
789826
- You cannot assume that an `asm!` block will appear exactly once in the output binary. The compiler is allowed to instantiate multiple copies of the `asm!` block, for example when the function containing it is inlined in multiple places.
790-
- As a consequence, you should only use [local labels] inside inline assembly code. Defining symbols in assembly code may lead to assembler and/or linker errors due to duplicate symbol definitions.
791827

792828
> **Note**: As a general rule, the flags covered by `preserves_flags` are those which are *not* preserved when performing a function call.
793-
794-
[local labels]: https://sourceware.org/binutils/docs/as/Symbol-Names.html#Local-Labels

0 commit comments

Comments
 (0)