2020-07-17
情報処理学会「情報処理」8月号の特集「プログラミング教育の最前線」(目次記事一覧
モダン言語全盛時代に、なぜBASICか?なぜはんだづけなのか?6,586文字、7ページで綴りました。コンピューター好きな人、増やしましょう!

気になるモダンプログラミング言語の1つ、Rust(ラスト)。Denoとrust4ijをきっかけに入門。 IchigoJam と、Arm Cortex-M0 マシン語を使って、C言語の代替手段にできるか検証開始!

Rustの特徴のひとつ、ゼロコスト抽象化は、C言語の構造体と構造体ポインタを使った関数群や、関数ポインタをすっきり記述できていい感じ。 trait(トレイト)は、C言語では関数ポインタで実装するJavaのインターフェイス的なもの、こちらもきれいな記述でゼロコスト。

メモリを扱う際にもよく使う配列、うっかり領域外アクセスがバグやセキュリティホールになりがちです。Rustでどのように防いでいるか逆アセンブルして確認してみました。

let mut ar:[i32; 4] = [1, 2, 3, 4]; ar[param as usize] = 100;

長さ4の配列を作って、パラメータで指定された場所に100を書き込むプログラム。4以上の値が指定されると領域外アクセス、まずいです。

14: 9100 str r1, [sp, #0] 16: 2803 cmp r0, #3 18: d80c bhi.n 0x34 1a: 0080 lsls r0, r0, #2 1c: 4669 mov r1, sp 1e: 2264 movs r2, #100 ; 0x64 20: 500a str r2, [r1, r0]

Rustでコンパイルしたコードを見てみると、配列の初期化後、「cmp r0, #3」で配列の長さ-1と比較し「bhi.n 0x34」で範囲外ならジャンプ(GOTO)させ、不正なプログラムを走らせないように保護するコードが生成されていました。 2命令、たった2クロックのオーバーヘッドなので、サイズ的にも速度的にも問題になることは少ないでしょう。

領域外として判定された際のジャンプ先が panic 処理となります。panic_handlerとして自由に定義できるので、試しにただのループに変更してみました。

use core::panic::PanicInfo; #[panic_handler] fn panic(_info: &PanicInfo) -< ! { loop {} }

すると、なんと、下記のように領域外チェックが消えました。仕様なのかどうなのかは未調査ですが、これならそこそこ攻めた作りもできそうです。

14: 9100 str r1, [sp, #0] 12: 0080 lsls r0, r0, #2 14: 4669 mov r1, sp 16: 2264 movs r2, #100 ; 0x64 18: 500a str r2, [r1, r0]

panic 処理内で、volatile_storeとunsafeを使って、不正なメモリアクセスをあえて実行して、IchigoJam BASICの「Segmentation Fault」を起こすようにすると使いやすくなります。

#![no_std] #![no_main] #![feature(core_intrinsics)] use rust4ij::std15::*; use core::intrinsics::volatile_store; use core::panic::PanicInfo; #[panic_handler] fn panic(_info: &PanicInfo) -> ! { //putstr("panic!\n".as_bytes().as_ptr()); // show message (+23byte) unsafe { volatile_store(1 as *mut i32, 1); } // invoke the Segmentation fault for safe (+32byte) loop {} } #[link_section = ".main"] #[no_mangle] fn main(param:i32, _ram:i32, _rom:i32, _divfunc: fn(u32,u32) -> u64) -> i32 { let mut ar:[i32; 4] = [1, 2, 3, 4]; ar[param as usize] = 100; let mut sum:i32 = 0; for i in 0..ar.len() { sum += ar[i]; } return sum; }

転送して、?USR(#800,4) と領域外アクセスするとエラーとなることが確認できます。不正アクセスするマシン語は下記のように、最小限のマシン語に変換されています。

44: 2001 movs r0, #1 46: 6000 str r0, [r0, #0]

前後に余計なコードが混ざってしまうため、数byte単位でも容量がほしい、現行 IchigoJam の移植はちょっと無理にしろ、かなり広範囲でのマイコン組み込み開発に良さそうです。

Rust、なかなかかわいく思えてきました。 次は、所有権の概念を使った動的メモリ確保を多用するメモアプリとかの実装にチャレンジして、より仲良くなってみようと思います。


創造はじめのいっぽ,Apple I/TK-80/MSX が生んだ感動をすべての子どもたちへ!」と題したIchigoJamにかけるこどもプログラミングの想いでも触れたコンピューター自体を理解し、好きになることと大切さ。

使うだけじゃなくて、IchigoJamみたいな素晴らしいハードウェアのきっかけになったのはすごく嬉しいことだ。あれは素晴らしい。
また英国がコンピューターの歴史を作るときが来た——「英国のMakerムーブメントは世界一」Raspberry Pi財団代表エベン・アプトンが語る | fabcross

Raspberry Pi、安価なパソコンをこども達に!想いに共感しに出会った2013年。小学生にはもう一段簡単なパソコンが必要と思って作った IchigoJam。 イベントを通じて、創始者、Eben Upton とも日本で会え、それがきっかけで産まれた IchigoJam RPi は、ラズパイで使えるサードパーティーOSとしても紹介してくれました!

世界中のこどもたちが「創造はじめのいっぽ」を楽しく踏み出せるよう、日々精進。

Tweet
クリエイティブ・コモンズ・ライセンス
本ブログの記事や写真は「Creative Commons — CC BY 4.0」の下に提供します。記事内で紹介するプログラムや作品は、それぞれに記載されたライセンスを参照ください。
CC BY / @taisukef / アイコン画像 / プロフィール画像 / 「一日一創」画像 / RSS