@@ -58,7 +58,7 @@ but you must add the right number of `:` if you skip them:
5858asm!("xor %eax, %eax"
5959 :
6060 :
61- : "eax"
61+ : "{ eax} "
6262 );
6363# } }
6464```
@@ -69,21 +69,21 @@ Whitespace also doesn't matter:
6969# #![feature(asm)]
7070# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
7171# fn main() { unsafe {
72- asm!("xor %eax, %eax" ::: "eax");
72+ asm!("xor %eax, %eax" ::: "{ eax} ");
7373# } }
7474```
7575
7676## Operands
7777
7878Input and output operands follow the same format: `:
7979"constraints1"(expr1), "constraints2"(expr2), ..."`. Output operand
80- expressions must be mutable lvalues:
80+ expressions must be mutable lvalues, or not yet assigned :
8181
8282```
8383# #![feature(asm)]
8484# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
8585fn add(a: i32, b: i32) -> i32 {
86- let mut c = 0 ;
86+ let c: i32 ;
8787 unsafe {
8888 asm!("add $2, $0"
8989 : "=r"(c)
@@ -100,6 +100,22 @@ fn main() {
100100}
101101```
102102
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+
103119## Clobbers
104120
105121Some instructions modify registers which might otherwise have held
@@ -112,7 +128,7 @@ stay valid.
112128# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
113129# fn main() { unsafe {
114130// 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} ");
116132# } }
117133```
118134
@@ -139,3 +155,14 @@ Current valid options are:
139155 the compiler to insert its usual stack alignment code
1401563 . * intel* - use intel syntax instead of the default AT&T.
141157
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