This commit is contained in:
chyyuu
2022-07-17 08:31:53 +00:00
parent fe475cccc8
commit c9505ea308
3 changed files with 55 additions and 54 deletions

View File

@@ -177,53 +177,51 @@ Rust 的 core 库内建了以一系列帮助实现显示字符的基本 Trait
syscall(SYSCALL_WRITE, [fd, buffer.as_ptr() as usize, buffer.len()])
}
然后实现基于 ``Write`` Trait 的数据结构,并完成 ``Write`` Trait 所需要的 ``write_str`` 函数,并用 ``print`` 函数进行包装。
然后实现基于 ``Write`` Trait 的数据结构,并完成 ``Write`` Trait 所需要的 ``write_str`` 函数,并用 ``print`` 函数进行包装。最后,基于 ``print`` 函数实现Rust语言 **格式化宏** ( `formatting macros <https://doc.rust-lang.org/std/fmt/#related-macros>`_ )。
.. code-block:: rust
// os/src/console.rs
// os/src/console.rs
use core::fmt::{Write, Arguments, Result};
use crate::sys_write;
struct Stdout;
struct Stdout;
impl Write for Stdout {
fn write_str(&mut self, s: &str) -> fmt::Result {
sys_write(1, s.as_bytes());
Ok(())
}
}
impl Write for Stdout {
fn write_str(&mut self, s: &str) -> Result {
sys_write(1, s.as_bytes());
Ok(())
}
}
pub fn print(args: fmt::Arguments) {
Stdout.write_fmt(args).unwrap();
}
pub fn print(args: Arguments) {
Stdout.write_fmt(args).unwrap();
}
最后,实现基于 ``print`` 函数实现Rust语言 **格式化宏** ( `formatting macros <https://doc.rust-lang.org/std/fmt/#related-macros>`_ )。
macro_rules! print {
($fmt: literal $(, $($arg: tt)+)?) => {
$crate::console::print(format_args!($fmt $(, $($arg)+)?));
}
}
macro_rules! println {
($fmt: literal $(, $($arg: tt)+)?) => {
$crate::console::print(format_args!(concat!($fmt, "\n") $(, $($arg)+)?));
}
}
注: ``os/src/console.rs`` 文件的代码中使用到了 ``main.rs`` 文件中的sys_write方法需要说明在文件头部声明 ``use crate::sys_write;`` 。
而 ``main.rs`` 为了能够用到 ``console.rs`` 提供的功能,也需要添加对 console 的引用。主要的添加如下:
.. code-block:: rust
// os/src/console.rs
// os/src/main.rs
macro_rules! print {
($fmt: literal $(, $($arg: tt)+)?) => {
$crate::console::print(format_args!($fmt $(, $($arg)+)?));
}
}
macro_rules! println {
($fmt: literal $(, $($arg: tt)+)?) => {
$crate::console::print(format_args!(concat!($fmt, "\n") $(, $($arg)+)?));
}
}
// os/src/main.rs
#![no_std]
#![no_main]
#[macro_use]
mod console;
mod lang_items;
//... other code
#[macro_use]
mod console;
//... other code
...
@@ -231,6 +229,8 @@ Rust 的 core 库内建了以一系列帮助实现显示字符的基本 Trait
.. code-block:: rust
// os/src/main.rs
#[no_mangle]
extern "C" fn _start() {
println!("Hello, world!");

View File

@@ -427,25 +427,23 @@
<span class="p">}</span><span class="w"></span>
</pre></div>
</div>
<p>然后实现基于 <code class="docutils literal notranslate"><span class="pre">Write</span></code> Trait 的数据结构,并完成 <code class="docutils literal notranslate"><span class="pre">Write</span></code> Trait 所需要的 <code class="docutils literal notranslate"><span class="pre">write_str</span></code> 函数,并用 <code class="docutils literal notranslate"><span class="pre">print</span></code> 函数进行包装。</p>
<div class="highlight-rust notranslate"><div class="highlight"><pre><span></span><span class="c1">// os/src/console.rs</span>
<p>然后实现基于 <code class="docutils literal notranslate"><span class="pre">Write</span></code> Trait 的数据结构,并完成 <code class="docutils literal notranslate"><span class="pre">Write</span></code> Trait 所需要的 <code class="docutils literal notranslate"><span class="pre">write_str</span></code> 函数,并用 <code class="docutils literal notranslate"><span class="pre">print</span></code> 函数进行包装。最后,基于 <code class="docutils literal notranslate"><span class="pre">print</span></code> 函数实现Rust语言 <strong>格式化宏</strong> ( <a class="reference external" href="https://doc.rust-lang.org/std/fmt/#related-macros">formatting macros</a> )。</p>
<div class="highlight-rust notranslate"><div class="highlight"><pre><span></span><span class="c1">// os/src/console.rs</span>
<span class="k">use</span><span class="w"> </span><span class="n">core</span>::<span class="n">fmt</span>::<span class="p">{</span><span class="n">Write</span><span class="p">,</span><span class="w"> </span><span class="n">Arguments</span><span class="p">,</span><span class="w"> </span><span class="nb">Result</span><span class="p">};</span><span class="w"></span>
<span class="k">use</span><span class="w"> </span><span class="k">crate</span>::<span class="n">sys_write</span><span class="p">;</span><span class="w"></span>
<span class="k">struct</span> <span class="nc">Stdout</span><span class="p">;</span><span class="w"></span>
<span class="k">impl</span><span class="w"> </span><span class="n">Write</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">Stdout</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="k">fn</span> <span class="nf">write_str</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">s</span>: <span class="kp">&amp;</span><span class="kt">str</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">fmt</span>::<span class="nb">Result</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="k">fn</span> <span class="nf">write_str</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">s</span>: <span class="kp">&amp;</span><span class="kt">str</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Result</span> <span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="n">sys_write</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">s</span><span class="p">.</span><span class="n">as_bytes</span><span class="p">());</span><span class="w"></span>
<span class="w"> </span><span class="nb">Ok</span><span class="p">(())</span><span class="w"></span>
<span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
<span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">print</span><span class="p">(</span><span class="n">args</span>: <span class="nc">fmt</span>::<span class="n">Arguments</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">print</span><span class="p">(</span><span class="n">args</span>: <span class="nc">Arguments</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="n">Stdout</span><span class="p">.</span><span class="n">write_fmt</span><span class="p">(</span><span class="n">args</span><span class="p">).</span><span class="n">unwrap</span><span class="p">();</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>
</div>
<p>最后,实现基于 <code class="docutils literal notranslate"><span class="pre">print</span></code> 函数实现Rust语言 <strong>格式化宏</strong> ( <a class="reference external" href="https://doc.rust-lang.org/std/fmt/#related-macros">formatting macros</a> )。</p>
<div class="highlight-rust notranslate"><div class="highlight"><pre><span></span><span class="c1">// os/src/console.rs</span>
<span class="fm">macro_rules!</span><span class="w"> </span><span class="n">print</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="p">(</span><span class="cp">$fmt</span>: <span class="nc">literal</span><span class="w"> </span><span class="cp">$(,</span><span class="w"> </span><span class="cp">$($arg</span>: <span class="nc">tt</span><span class="p">)</span><span class="o">+</span><span class="p">)</span><span class="o">?</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
@@ -455,24 +453,27 @@
<span class="fm">macro_rules!</span><span class="w"> </span><span class="n">println</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="p">(</span><span class="cp">$fmt</span>: <span class="nc">literal</span><span class="w"> </span><span class="cp">$(,</span><span class="w"> </span><span class="cp">$($arg</span>: <span class="nc">tt</span><span class="p">)</span><span class="o">+</span><span class="p">)</span><span class="o">?</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="cp">$crate</span>::<span class="n">console</span>::<span class="n">print</span><span class="p">(</span><span class="fm">format_args!</span><span class="p">(</span><span class="fm">concat!</span><span class="p">(</span><span class="cp">$fmt</span><span class="p">,</span><span class="w"> </span><span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">)</span><span class="w"> </span><span class="cp">$(,</span><span class="w"> </span><span class="cp">$($arg</span><span class="p">)</span><span class="o">+</span><span class="p">)</span><span class="o">?</span><span class="p">));</span><span class="w"></span>
<span class="w"> </span><span class="cp">$crate</span>::<span class="n">console</span>::<span class="n">print</span><span class="p">(</span><span class="fm">format_args!</span><span class="p">(</span><span class="fm">concat!</span><span class="p">(</span><span class="cp">$fmt</span><span class="p">,</span><span class="w"> </span><span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">)</span><span class="w"> </span><span class="cp">$(,</span><span class="w"> </span><span class="cp">$($arg</span><span class="p">)</span><span class="o">+</span><span class="p">)</span><span class="o">?</span><span class="p">));</span><span class="w"></span>
<span class="w"> </span><span class="p">}</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</pre></div>
</div>
<p>注: <code class="docutils literal notranslate"><span class="pre">os/src/console.rs</span></code> 文件的代码中使用到了 <code class="docutils literal notranslate"><span class="pre">main.rs</span></code> 文件中的sys_write方法需要说明在文件头部声明 <code class="docutils literal notranslate"><span class="pre">use</span> <span class="pre">crate::sys_write;</span></code></p>
<p><code class="docutils literal notranslate"><span class="pre">main.rs</span></code> 为了能够用到 <code class="docutils literal notranslate"><span class="pre">console.rs</span></code> 提供的功能,也需要添加对 console 的引用。主要的添加如下:</p>
<div class="highlight-rust notranslate"><div class="highlight"><pre><span></span><span class="w"> </span><span class="c1">// os/src/main.rs</span>
<span class="c1">// os/src/main.rs</span>
<span class="cp">#![no_std]</span><span class="w"></span>
<span class="cp">#![no_main]</span><span class="w"></span>
<span class="cp">#[macro_use]</span><span class="w"></span>
<span class="k">mod</span> <span class="nn">console</span><span class="p">;</span><span class="w"></span>
<span class="k">mod</span> <span class="nn">lang_items</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="c1">//... other code</span>
<span class="w"> </span><span class="cp">#[macro_use]</span><span class="w"></span>
<span class="w"> </span><span class="k">mod</span> <span class="nn">console</span><span class="p">;</span><span class="w"></span>
<span class="w"> </span><span class="c1">//... other code</span>
<span class="o">..</span><span class="p">.</span><span class="w"></span>
</pre></div>
</div>
<p>接下来,我们调整一下应用程序,让它发出显示字符串和退出的请求:</p>
<div class="highlight-rust notranslate"><div class="highlight"><pre><span></span><span class="cp">#[no_mangle]</span><span class="w"></span>
<div class="highlight-rust notranslate"><div class="highlight"><pre><span></span><span class="c1">// os/src/main.rs</span>
<span class="cp">#[no_mangle]</span><span class="w"></span>
<span class="k">extern</span><span class="w"> </span><span class="s">"C"</span><span class="w"> </span><span class="k">fn</span> <span class="nf">_start</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"Hello, world!"</span><span class="p">);</span><span class="w"></span>
<span class="w"> </span><span class="n">sys_exit</span><span class="p">(</span><span class="mi">9</span><span class="p">);</span><span class="w"></span>

File diff suppressed because one or more lines are too long