tomoyuki-nakabayashi / Rustemu86

Apache License 2.0
5 stars 0 forks source link

インラインアセンブラを使わずにRustから"Hello"する #18

Closed tomoyuki-nakabayashi closed 6 years ago

tomoyuki-nakabayashi commented 6 years ago

インライン地獄なので。

tomoyuki-nakabayashi commented 6 years ago

blogosってどうやって文字列扱っていたんだっけ?ヒープ使う気がするが。

tomoyuki-nakabayashi commented 6 years ago
static HELLO: &[u8] = b"Hello from Rust!";

#[no_mangle]
pub extern fn rust_main() {
  let uart16550 = 0x10000000 as *mut u8;
  for &byte in HELLO.iter() {
    unsafe {
      *uart16550 = byte;
    }
  }
}

最適化されて、!の書き込みしか残らない。 volatileを使おう。

tomoyuki-nakabayashi commented 6 years ago

https://stackoverflow.com/questions/48040146/error-loading-target-specification-could-not-find-specification-for-target

xargoがバグっていて、RUST_TARGET_PATH=$(shell pwd)をxargo前に書かないとクロスビルドされないらしい。

tomoyuki-nakabayashi commented 6 years ago

Volatileの使い方を見直そう。

error[E0308]: mismatched types
  --> src/lib.rs:16:23
   |
16 |       uart16550.write(byte);
   |                       ^^^^
   |                       |
   |                       expected struct `volatile::Volatile`, found u8
   |                       help: try using a variant of the expected type: `volatile::Volatile(byte)`
   |
   = note: expected type `volatile::Volatile<u8>`
              found type `u8`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
error: Could not compile `hello`.
tomoyuki-nakabayashi commented 6 years ago

これで良いらしい。テストコード見て初めて使い方が分かった。 https://docs.rs/volatile/0.2.4/src/volatile/lib.rs.html#1-300

extern crate volatile;
use volatile::Volatile;

static HELLO: &[u8] = b"Hello from Rust!";

#[no_mangle]
pub extern fn rust_main() {
  let uart16550 = 0x10000000 as *mut Volatile<u8>;

  for &byte in HELLO.iter() {
    unsafe {
      (*uart16550).write(byte);
    }
  }
}

ということで、movだけ実装すれば何とかなる。

00000010  C604250000001048  mov byte [0x10000000],0x48
00000018  C604250000001065  mov byte [0x10000000],0x65
00000020  C60425000000106C  mov byte [0x10000000],0x6c
00000028  C60425000000106C  mov byte [0x10000000],0x6c
00000030  C60425000000106F  mov byte [0x10000000],0x6f
00000038  C604250000001020  mov byte [0x10000000],0x20
00000040  C604250000001066  mov byte [0x10000000],0x66
00000048  C604250000001072  mov byte [0x10000000],0x72
00000050  C60425000000106F  mov byte [0x10000000],0x6f
00000058  C60425000000106D  mov byte [0x10000000],0x6d
00000060  C604250000001020  mov byte [0x10000000],0x20
00000068  C604250000001052  mov byte [0x10000000],0x52
00000070  C604250000001075  mov byte [0x10000000],0x75
00000078  C604250000001073  mov byte [0x10000000],0x73
00000080  C604250000001074  mov byte [0x10000000],0x74
00000088  C604250000001021  mov byte [0x10000000],0x21
tomoyuki-nakabayashi commented 6 years ago

これどういう命令なんだ?

tomoyuki-nakabayashi commented 6 years ago

0x04は位置的にModRM。0x25はSIBか。

0x04であれば、Mod: 0b00のr/m: 0b100なので、[SIB]になる。

tomoyuki-nakabayashi commented 6 years ago

SIB

  7                           0
+---+---+---+---+---+---+---+---+
| scale |   index   |    base   |
+---+---+---+---+---+---+---+---+
tomoyuki-nakabayashi commented 6 years ago

0x25だから、

scale: 0b00 index: 0b100 base: 0b101

ModRMのmodは0b00。

tomoyuki-nakabayashi commented 6 years ago

うへぇ、これSIBってModのモードフィールド使うんか。えっぐ。

tomoyuki-nakabayashi commented 6 years ago

この設定だと、index register/base register、ともに利用せず、だな。 つじつまが合った。

tomoyuki-nakabayashi commented 6 years ago

とりあえずフェッチを作ろう。

tomoyuki-nakabayashi commented 6 years ago

とりあえず完成した。がリファクタリングが必要だ…。