@@ -58,7 +58,7 @@ but you must add the right number of `:` if you skip them:
58
58
asm!("xor %eax, %eax"
59
59
:
60
60
:
61
- : "eax"
61
+ : "{ eax} "
62
62
);
63
63
# } }
64
64
```
@@ -69,21 +69,21 @@ Whitespace also doesn't matter:
69
69
# #![feature(asm)]
70
70
# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
71
71
# fn main() { unsafe {
72
- asm!("xor %eax, %eax" ::: "eax");
72
+ asm!("xor %eax, %eax" ::: "{ eax} ");
73
73
# } }
74
74
```
75
75
76
76
## Operands
77
77
78
78
Input and output operands follow the same format: `:
79
79
"constraints1"(expr1), "constraints2"(expr2), ..."`. Output operand
80
- expressions must be mutable lvalues:
80
+ expressions must be mutable lvalues, or not yet assigned :
81
81
82
82
```
83
83
# #![feature(asm)]
84
84
# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
85
85
fn add(a: i32, b: i32) -> i32 {
86
- let mut c = 0 ;
86
+ let c: i32 ;
87
87
unsafe {
88
88
asm!("add $2, $0"
89
89
: "=r"(c)
@@ -100,6 +100,22 @@ fn main() {
100
100
}
101
101
```
102
102
103
+ If you would like to use real operands in this position, however,
104
+ you are required to put curly braces ` {} ` around the register that
105
+ you want, and you are required to put the specific size of the
106
+ operand. This is useful for very low level programming, where
107
+ which register you use is important:
108
+
109
+ ```
110
+ # #![feature(asm)]
111
+ # #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
112
+ # unsafe fn read_byte_in(port: u16) -> u8 {
113
+ let result: u8;
114
+ asm!("in %dx, %al" : "={al}"(result) : "{dx}"(port));
115
+ result
116
+ # }
117
+ ```
118
+
103
119
## Clobbers
104
120
105
121
Some instructions modify registers which might otherwise have held
@@ -112,7 +128,7 @@ stay valid.
112
128
# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
113
129
# fn main() { unsafe {
114
130
// Put the value 0x200 in eax
115
- asm!("mov $$0x200, %eax" : /* no outputs */ : /* no inputs */ : "eax");
131
+ asm!("mov $$0x200, %eax" : /* no outputs */ : /* no inputs */ : "{ eax} ");
116
132
# } }
117
133
```
118
134
@@ -139,3 +155,14 @@ Current valid options are:
139
155
the compiler to insert its usual stack alignment code
140
156
3 . * intel* - use intel syntax instead of the default AT&T.
141
157
158
+ ```
159
+ # #![feature(asm)]
160
+ # #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
161
+ # fn main() {
162
+ let result: i32;
163
+ unsafe {
164
+ asm!("mov eax, 2" : "={eax}"(result) : : : "intel")
165
+ }
166
+ println!("eax is currently {}", result);
167
+ # }
168
+ ```
0 commit comments