读取输入
use std::io;
fn main() {println!("please enter your name");
let mut name = String::new();
let greeting: &str = "nice to meet you";
io::stdin().read_line(&mut name).expect("No input!!");
println!("hello,{}!{}", name.trim(), greeting);
}
一个简单的程序,用 linux 进行编译
得到伪代码
__int64 __fastcall input::main()
{
__int64 v0; // rax
__int64 v1; // rdx
__int64 v2; // rdx
__int64 v3; // rdx
__int64 v4; // rax
__int64 v5; // rdx
__int64 v7; // [rsp+0h] [rbp-138h]
__int64 v8; // [rsp+8h] [rbp-130h]
char v9[48]; // [rsp+58h] [rbp-E0h] BYREF
char v10[24]; // [rsp+88h] [rbp-B0h] BYREF
__int64 v11[2]; // [rsp+A0h] [rbp-98h] BYREF
char v12[16]; // [rsp+B0h] [rbp-88h] BYREF
__int64 v13; // [rsp+C0h] [rbp-78h] BYREF
char v14[48]; // [rsp+C8h] [rbp-70h] BYREF
__int64 v15[4]; // [rsp+F8h] [rbp-40h] BYREF
__int64 v16[2]; // [rsp+118h] [rbp-20h] BYREF
core::fmt::Arguments::new_v1(
v9,
&off_51098,
1LL,
"nice to meet youNo input!!input.rshello,!\n/builddir/build/BUILD/rustc-1.62.1-src/library/core/src/alloc/layout.rs",
0LL);
std::io::stdio::_print::h9caedd389253d970(v9);
alloc::string::String::new(v10);
v11[0] = (__int64)"nice to meet youNo input!!input.rshello,!\n"
"/builddir/build/BUILD/rustc-1.62.1-src/library/core/src/alloc/layout.rs";
v11[1] = 16LL;
v13 = std::io::stdio::stdin::hfc1b5b4a69e923b5();
std::io::stdio::Stdin::read_line::h8f22ef68407258cc(v12, &v13, v10);
core::result::Result<TE>::expect(
v12,
"No input!!input.rshello,!\n/builddir/build/BUILD/rustc-1.62.1-src/library/core/src/alloc/layout.rs",
10LL,
&off_510A8);
v0 = <alloc::string::String_as_core::ops::deref::Deref>::deref(v10);
v16[0] = core::str::<impl_str>::trim(v0, v1);
v16[1] = v2;
v7 = core::fmt::ArgumentV1::new_display(v16);
v8 = v3;
v4 = core::fmt::ArgumentV1::new_display(v11);
v15[0] = v7;
v15[1] = v8;
v15[2] = v4;
v15[3] = v5;
core::fmt::Arguments::new_v1(v14, &off_510C0, 3LL, v15, 2LL);
std::io::stdio::_print::h9caedd389253d970(v14);
return core::ptr::drop_in_place<alloc::string::String>(v10);
}
首先看 off_51098,也就是上一篇里面我们写到的 rust 字符串储存的地方
不难看出,其实 ida 的伪代码难看的原因很简单,就是没有能够把字符串分开来,导致它认为最开始储存的地方才是真正的字符串,因此前面后面的一些字符串也被显示到了伪代码中。按一下 u,然后在正确的位置重新创建字符串,就有上一篇中的效果了。
这一段就很清晰了,很显然就是初始化了 String 对象和输入流,然后读取了输入
需要注意的是 expect,在 c 语言的伪代码里面,第一个参数实际上是 rs 中的 Result 枚举,而后面看到的那个 offset,实际上是我们在 expect 失败时候抛出的 panic 信息。
之后就是解引用,trim。这个很好懂,但是最后我们进行了格式化字符串,这个就很不好看了。
格式化字符串
string 没啥好说的,使用 new_display 函数可以在一个字符串中间插东西,这也是 rs 格式化字符串的原理
看个奇怪的
fn main() {
let x = 2;
let y = 2;
println!("x is {}", x);
println!("y is {}", y);
println!("x+y is {}", x+y);
}
很显然,第一行里面储存数据被编译器优化了
只要再看几个例子就懂了
不多说,看图
正文完