Moiz's journal

プログラミングやFPGAなどの技術系の趣味に関するブログです

アメリカでがん治療をうける

はじめに

今年の前半、初期の大腸がん(直腸がん)になり直腸の一部摘出手術を受けた。
幸いなことに一回の手術で治療は終了し、今はほぼ通常の生活にもどっているが、自分にとっては生き方を見直す契機になる大きな出来事だった。

病気になってから調べたのだが、大腸がんの治療自体は日本でもアメリカでも大きな差はないようだ。しかし、アメリカの医療というと日本人にとってはどうしても高額、理不尽な保険制度、などといったイメージがあると思うし、アメリカでがん治療を受けたと聞けばいったいいくらかかるのか、と疑問に思う方も多いと思う。
このエントリーではそういった点についてまとめてみようと思う。

なおこのブログエントリーはあくまで私個人の経験についてまとめたもので、アメリカのがん治療の全体像を反映するものではありません。またブログオーナーは単なる患者であり、医療については素人なので、内容の正確性については保証できかねます。

がん治療の費用

がん治療および検査にかかった費用のうち大きなものを表にしてみた。

内容

請求額 保険会社が認めた額 自己負担額 説明
内視鏡検査
(病院)
 $ 2,833 $462 $0 予防的処置なので保険100%適用
内視鏡検査
(施設)
$19,800 $1,487 $0 内視鏡検査の請求はなぜかドクターの病院と、検査施設(内視鏡専用の施設らしい)との2通にわかれていた。こちらも予防的処置なので保険100%適用
病理検査 $2,105 $1,473 $1,473 内視鏡検査後の病理検査
再検査
(病院)
$2,700 $341 $341 超音波検査
再検査
(施設)
$17,363 $10,662 $2,564 このあたりで免責額に届いたらしく、自己負担の割合が減った
再検査
(麻酔)
$2,241 $719 $72 麻酔費用は別に請求された
CT検査 $968 $489 $49  
MRI検査 $16,668 $9,027 $0 自己負担額の上限に届いたらしく、自己負担額が$0になった
事前検査 $3,205 $1,852 $0 手術前の検査
手術前検査 $1,885 $1,124 $0 当日の検査
病院の費用 $156,728 $36,816 $0 病院や病室の費用。個室に4日間いた。
手術 $10,419 $7,315 $0 腹腔鏡手術による直腸がん切除
麻酔 $2,048 $792 $0  
総額 $271,829 $90,774 $5,203 診察、薬など、この表に含まれない費用を含んだ額

 

追記:再検査の際、可能であれば腫瘍を取り除く処置を行う予定だったので、費用がかさんだのだと思われる。

こうしてみると、請求額、保険会社認めた額(実際に医療機関に支払われる額)、自己負担の乖離が大きい。

まず請求額は基本的に医療機関の言い値で、病院ごとに請求額は大きく異る。例えば「日米がん格差 「医療の質」と「コスト」の経済学 (アキよしかわ)」には病院ごとの費用のばらつきが例示されている。今回私が手術を受けたのは割と値段の張る病院だったようだ。

 次に、医療機関が主張する金額を、保険会社が交渉して適正な額に補正する。ただし、保険会社が認める額もあくまで交渉の結果であり、同じ医療行為だとしても必ずしも同じ金額にはならないようだ。このあたり、日本の保険点数制度の明朗会計に慣れた身としては未だにうまくなじめない。

次に自己負担額が高かったり低かったりするのは、私の入っているHDHP(High Deductible Health Plan - 高免責医療プランとでも訳すのだろうか)というプランの性質による。このプランでは、ある一定額までは医療費は患者の全額自己負担となる。この額を超えると大部分(私の場合90%)が保険で賄われ、さらに自己負担上限に達すると全額保険で支払われる。そんなわけで治療の初期には全額自己負担になり、後半では自己負担はゼロになる。HDHPではさらに免税で医療費をある程度の額まで支払う仕組み(HSA)もあり、実際の負担感はさらに上の表から感じられるものより低い。

追記:医療費は高いが代わりに(?)サービス面は非常に高かった。病室はトイレ・シャワー付きの完全個室の部屋(写真)で壁掛けテレビとiPadがついていた。

f:id:uzusayuu:20210421162639j:plain

広々とした病室(個室)からの眺め

食事はルームサービスで好きなときに好きなものを注文できる(ただし状況により食べて良いものは指導される)。 

f:id:uzusayuu:20210423124726j:plain

病室のルームサービスで頼んだ料理。あまり食べられなかった。

治療について

最初にも書いたとおり、私の場合初期に発見されたために一度の手術で治療を終える事ができた。もしステージが進んでいれば他の治療も受けることになり、身体的な負担は大きく増えただろうし、上記の治療費用も遥かに大きなものになっただろう。

追記:4日で退院したのは予想していたこととはいえ大変だった。帰ってもずっと横になっていて家族にたよりきりだった。一人暮らしだったらどうなっていたかと思うとぞっとする。

治療自体は日本語で読んだ本などと比べる限り、日本で受けるものと大きく差は無いようだ。(ただ本職のお医者さんに聞いたところ、素人にはわかりにくいような違いはあるようだ。)このあたり、大腸がんの治療は標準化がすすんでいる、という面もあるのかもしれないし、私の状況が初期だったから、という面もあるのかも知れない。

日本語でがん治療についてしらべる際に読んだ本は次のようなものだ。

 

 標準治療を強くすすめる本。また、治療以外にどのような検査で有用性が認められているかも解説されている。この本によると大腸癌はがん検診が推奨されるがんの一つで、特に便潜血検査は有用だということだ。

 

 

 こちらはちょっと古いが、わかりやすかった。2019年版の医師用のガイドラインも手に入れて読んでみたが、そちらは当然ながらやはり専門家向けで、よく理解できなかった。

 

 

 こちらも一般向けの標準治療解説。患者向けガイドラインと合わせて読んだ。こちらの方が少し新しいようだ。

治療自体以外の状況については次のような本を読んだ。

 

 

 これは本文中でも引用したが、ご自身が大腸癌患者となり日米で治療をうけた医療経済学者のアキよしかわ氏がご自身の経験と日米のがん治療の違いをまとめたもの。がん治療の費用は症状や治療法、またアメリカでは医療機関により大きく異なるので、そのような点に関してくわしく知りたい方はこちらの本を参照されることをおすすめする。

患者からみたがん治療については次の2つのまんがを読んだ。

 

 まんが家のひるなま氏が、ご自身の大腸癌の発見から治療までを描かれたまんが。この本の存在を知ったのは手術後だが、いろいろ共感する面も多く、自宅療養中に3回位読んだ。

 

 内田春菊氏ご自身の直腸がんの体験をつづったまんが。検査のようすや、手術後の様子など、私のケースと似ている面が多かった。

 まとめ

 自分は初期の段階でがんが発見されたため、比較的短い期間に治療を終わらせ日常にもどることができた。「最高のがん治療」にもあるとおり、大腸癌は早期発見により治療可能ながんの一つであり、便潜血などの検査が有効なようだ。私のがんも便潜血検査で発見されたのだが、自分が治療を終える頃にちょうどアメリカで便潜血検査の推奨年齢を引き下げるというニュースがあった。もしこの推奨年齢引き下げが早く行われていれば、自分のがんも更に早期に見つかり内視鏡手術ですんだのかもしれないと思うと、なるべく多くの人に検査を受けてほしいという思いが強くなる。

 

Interface誌2020年7月号に当ブログの記事と類似性の高い記事が掲載された件について

Interface誌2020年7月号に当ブログの記事と類似性の高い記事が掲載された件について

はじめに

当ブログ及びそれをもとにした同人誌「PythonとColabでできる ゼロから作るRAW現像」の内容と非常に類似性の高い記事が、私の知らない間に商用雑誌に掲載されるという事がありましたので、その経緯についてまとめます。

類似性の高い記事について

Interface誌(CQ出版社)の2020年7月号特集記事「AI時代の画像処理教科書」において、当ブログ及びそれをもとにした同人誌「PythonとColabでできる ゼロから作るRAW現像」の内容と非常に類似性の高い記事が掲載されました。私への事前連絡などはありませんでした。

具体的には特集第1章「ディジタル画像の基礎知識」において、24-25ページおよび27ページの内容が、当ブログの2018-9023の記事「ゼロから作るRAW現像その1-基本的な処理」と非常に似通っています。 類似点は単に内容の類似性にとどまらず、多くの文章はほぼそのまま、または小さな変更のみの形で雑誌記事にとりこまれていました。また、非常に似通った図も使用されています。

例1

Interface誌24ページ

イメージセンサは碁盤の目状に並んだ小さなフォトセンサの集まりでできています.1つ1つのフォトセンサは,そのままでは色の違いを識別できません.

当ブログ

画像センサーは、碁盤の目状にならんだ小さな光センサーの集まりでできています。一つ一つの光センサーはそのままでは色の違いを認識できません。

例2

Interface誌25ページ

カメラ用のイメージセンサでは,2000年代初頭までは補色フィルタや3板式もそれなりの割合で使われていたのですが,イメージセンサの性能向上やカメラの小型化,高解像度化の流れの中で,ほとんどがベイヤー配列に変わりました。

当ブログ

カメラ用センサーでは2000年代初頭までは、補色フィルターや3板方式もそれなりの割合で使われていたのですが、センサーの性能向上やカメラの小型化と高画質化の流れの中でほとんどがBayer方式にかわりました。

この他に、第4章「プログラミング体験」の内容も、当ブログと似通っています。

特集の第1章では当ブログ記事が参考文献としてあげられてはいますが、私としては量・形式ともに正当と認められている範囲を大きく逸脱していると考えました。

Interface誌の対応

この点についてTwitterでInterface誌に問い合わせたところ、以下のような記事の類似性を認める回答及び謝罪がありました。

また、別途、編集部から私の方に、直接の謝罪と、編集部として10月号に謝罪文を掲載する予定であることが伝えられました。

実際に、8月25日に発売されたInterface誌10月号171ページにおいて、「読者の皆様へ」という文章がが掲載されている事を確認しました。

この文章では、Interface誌7月号の記事と当ブログ記事の類似性が高いことを認め、対象となる記事と当ブログの内容を説明し、謝罪の言葉をのべています。

私が第一に求めたかったことは、当該の記事が私の記事を元にしたことである事を公の形で認めてもらう事でしたので、これで私としてはこの件については終了したいと思っています。

(ただし、これは当ブログについての著作権等を放棄するものではありません。)

なお、謝罪文と同時に掲載された私の同人誌の案内は私が要求したものではありませんが、上記の記事が私の記事を元にしたことを周知させるにあたって有用と判断したため、編集部の考えの通りにしてもらいました。

支援くださった方々へ

該当のブログ記事を執筆中から非常に熱心なフィードバックをくださり、同人誌にも協力していただいたからあげさん(id:karaage)には、相談に乗っていただいた上ブログ記事でこの件をとりあげていただきました。 Interface誌に謝罪が載るまではこの件について取り上げないようにしようと考えていたためにお礼が遅れてしまいましたが、からあげ氏にはこの場を借りて改めて感謝させていただきます。

また、この件について、Interface誌への連絡がTwitterというオープンな手法であったために、ツイッター上でのあたたかい励ましの声を多数いただきました。

この他に、同人誌「ゼロから作るRAW現像」を支援として購入いただいた方も多数いらっしゃいました。

私自身非常に意気消沈する出来事だっただけに、こういった支援の声が大きな励みになりました。 あらためてこの件について温かい言葉をかけていただいた方、また同人誌を購入頂いた方々に、感謝したいと思います。

ありがとうございました。

ラズベリーパイ4にCLionをインストール

CLionとラズベリーパイ4

はじめに

先日まで知らなかったのですが、CLionやPyCharmはラズベリーパイで動作するようです。

とくにしかけは必要ありません。ただ配布されているパッケージをインストールするだけです。 どうやらCLionやPyCharm含めたIntelliJ系のIDEはほとんどの部分Javaで動作しているようです。

ただし、オフィシャルにサポートされているわけではないようなので、試される方は自己責任で実行ください。

また、当ブログの著者はこのブログで紹介した内容を実行した結果について、いかなる責任も負いかねます。

CLionをラズベリーパイ4にインストール

CLionをラズベリーパイ4にインストールしてみます。使用した機種はRaspberry Pi 4B 4GB版で、OSはRaspbian OSの32bit版(Buster)です。

Raspberry Pi OSの64bit版でもインストールできましたが、手順に一部細かな違いがありますので、そういった点も紹介します。

まずはLinux版のパッケージをダウンロードします。

f:id:uzusayuu:20200608054748p:plain
CLionのダウンロードページ

ダウンロードしたら解凍して、インストールしたいフォルダに移動します。 今回は/home/pi/bin/にインストールしました。

# ダウンロードしたフォルダで実行
# ファイル名はダウンロードした実際のファイルに一致させる
tar -xvf CLion-2020.1.2.tar.gz

# インストールしたいフォルダを指定。今回は~/bin/にインストールする。
mkdir -p /home/pi/bin
mv clion-2020.1.2 /home/pi/bin

Java VMがインストールされていなければ、インストールします。 自分が試したところ、64bit版のRaspberry Pi OSではデフォルトではインストールされていませんでした。

sudo apt update
sudo apt install default-jdk

あとはbinフォルダ以下のclion.shを実行します。

/home/pi/bin/clion-2020.1.2/bin/clion.sh

うまく動作すれば、プライバシーライセンスなどの確認画面が表示されますので、レビューして問題なければ許諾して進みます。

初回起動時はスクリプトの設定やプラグインの設定画面がでます。今回はデフォルトのままで進みます。

また、途中でライセンスの確認画面が出るので、ライセンスを持っている場合は入力する必要があります。なければ評価版として進めて行きます

CLionの実行環境の設定

初回の実行時、自分の環境ではこのような設定画面が表示されました。

f:id:uzusayuu:20200608054901p:plain
CLion設定、変更前

どうもバンドルされているcmakeが実行できないのが原因のようです。おそらくx86用のものしか付属しないのでしょう。

解決するためにcmakeをインストールして、CLionに設定します。

sudo apt install cmake

cmakeとgdbのパスを設定すると、のこりは自動で設定されます。

f:id:uzusayuu:20200608054945p:plain
CLion設定、変更後

これでCLionが起動できます。

f:id:uzusayuu:20200608055032p:plain
CLion起動画面

CLionの動作確認

この節は単なる動作確認です。 通常のLinuxでの動作と同じなので、CLionをご存知の方は読み飛ばしても問題ありません。

さっそくNew Projectを選んでみましょう。C++ Executableを選択して、LOCATIONをhelloにします。

f:id:uzusayuu:20200608055111p:plain
New Project

Createをクリックして次にすすみます。

すでに"Hello, world!"と表示するデフォルトのmain.cppができています。

f:id:uzusayuu:20200608055133p:plain
hello world code

右上の三角形をクリックして実行します。

f:id:uzusayuu:20200608055154p:plain
Hello world execution

Hello, world!と表示されました。動作確認成功です。

追加の設定

2回めの起動以降、外部のファイルをモニターするfsnotifierが動作しないという警告が表示されました。 これは、fsnotifierをコンパイルしてパスの設定をすることで回避できます。くわしくはこちらを参照ください。

Compiling File Watcher - IntelliJ IDEA - Confluence

上記の記事にしたがって、必要な実行ファイルを作成してCLionに設定してみます。

まず適当なフォルダを作って、その中で以下のコマンド実行して必要なファイルをダウンロードします。 これは一つ一つブラウザなどからダウンロードしても構いません

wget https://raw.githubusercontent.com/JetBrains/intellij-community/master/native/fsNotifier/linux/fsnotifier.h
wget https://raw.githubusercontent.com/JetBrains/intellij-community/master/native/fsNotifier/linux/inotify.c
wget https://raw.githubusercontent.com/JetBrains/intellij-community/master/native/fsNotifier/linux/main.c
wget https://raw.githubusercontent.com/JetBrains/intellij-community/master/native/fsNotifier/linux/make.sh
wget https://raw.githubusercontent.com/JetBrains/intellij-community/master/native/fsNotifier/linux/util.c

次にmake.shを実行します。

chmod u+x make.sh
./make.sh

32bit版だと、fsnotifier-armv7lというファイルができています。(64bit版ではfsnotifier-aarch64)

これをpycharmのbinフォルダにコピーします。 以下は先程のインストールパスの場合の例です。違うフォルダにインストールした場合は、そのフォルダにコピーしてください。

cp fsnotifier-armv7l ~/bin/clion-2020.1.2/bin/

CLionに戻って、Help -> Edit Custom Propertiesを選択します。ファイルを作るか聞かれたらYesを押して作成します。

以下の行を入力して、セーブします。

32bit版の場合

idea.filewatcher.executable.path = fsnotifier-armv7l

64bit版の場合

idea.filewatcher.executable.path = fsnotifier-aarch64

f:id:uzusayuu:20200608055221p:plain

これでfsnotifierに関する警告はでなくなると思います。

その他のIntelliJ製品

Raspbian上にPyCharm CEをインストールしてみたところ、こちらもインストールができました。

f:id:uzusayuu:20200608031309p:plain

まとめ

ラズベリーパイ4にCLionをインストールしてみました。 最低限必要な事前準備ははJava VMがインストールされている事と、cmakeなどのC++開発自体に必要な環境が構築されていることを確認することだけです。

自分自身インストールしたばかりでどんな使い勝手かまだわかりませんし、どんな不具合があるかも予想できませんが、いろいろ試してみようと思います。

Nexdock 2 を買いました

Nextdock 2 を買いました

去年注文したNexdock 2が一月ほど前に届きました。

f:id:uzusayuu:20200607144519j:plain
NexDock 2 とラズベリーパイ4

最初は癖があって使いにくいと思ったのですが、使いこなし方のコツを覚えたらだいぶ実用的になりました。

NextDock って?

NexDockというのは、FullHDモニターとキーボード、バッテリーが一体化した製品です。

nexdock.com

ノートPCとの最大の違いは、プロセッサやストレージが載っていない点です。PCや外部ディスプレイ対応のスマートフォンを接続して使うのが前提です。 私はラズベリーパイ4を接続してつかっています。

私が使っているのはNexDock 2ですが、こちらはもう注文を受け付けていないようです。 今はタッチ機能付きのNexDock Touchの注文を受け付けているようです。

使い勝手の方ですが、とっつきは良くないものの、うまく使いこなせれば悪くないと思います。 ただ、自分もなれるまで苦労したので、そういう試行錯誤や不安定さが許容できない人(例えば仕事で本格的に使いたいなど)は、事前に調査してから購入された方が良いと思います。

ラズベリーパイとの接続

ラズベリーパイとの接続には、USBケーブルと、HDMIケーブルを使います。 癖があるというのは主にこの部分に関するものです。

マニュアル通りに接続すると、NexDock2 とラズベリーパイの間の接続は*1

  • Raspberry Pi Micro HDMI 出力 -> Micro HDMI to HDMI 変換器 -> HDMIケーブル -> NexDock2 HDMI
  • Raspberry Pi USB Type-A -> 専用ケーブルのUSB Type-A端子 -> Nex Doc 2 USB Type-C
  • Raspberry Pi USB Type-C 電源 -> Type-C to Micro USB 変換器 -> 専用ケーブルのMicro USB端子 -> NexDock 2 USB Type-C

となります。(なお、ケーブルや変換器はすべて製品パッケージに含まれています。) どうもこの接続が厄介で、

  • 変換器に力がかかりやすい
  • 専用ケーブルが二股な上、硬くて扱いにくい
  • USB接続が不安定な気がする
  • 専用ケーブルがさせるNexDock 2 USB Type-Cポートは特定の一つだけで間違えやすい

といった問題がありました。とくに不安定なのは問題で、ボタンを押していないのに特定のキー入力が続いたりすることまでありました。 ただこのあたりは

  • 使いやすいMicro HDMI to HDMIケーブルにとりかえ
  • 専用ケーブルをやめ、USB Type-C ケーブルを使う

という方法で改善できました。

特に後者はマニュアルには記載がなかったのですが、NexDock2のサポートページに方法がのっていました ラズベリーパイのconfig.txtに以下の行を付け加えると、ラズベリーパイ4の電源用USB Type-C端子が、USB接続にも使えるようになるそうです。

# USB Type-C Host
dtoverlay=dwc2,dr_mode=host

ラズベリーパイの電源端子は電源専用だと思っていたので驚きました。

これで接続に必要なケーブルが2本に減り、しかも専用ケーブルを使わずにすむのでだいぶスッキリしました。 ケーブルの取り回しが楽になったので、ラズベリーパイ本体をモニター裏に貼り付ける、なんてこともやりやすくなりました。

f:id:uzusayuu:20200607150846j:plain

その他のTip

その他の問題と、改善方法を紹介します

タッチパッドが敏感すぎる

タッチパッドが大きい上に敏感なので、キー入力中についつい触れてしまうことがありました。 こちらはフォーラムで「Fn + ESCでタッチパッドが一時的にオフにできる」という投稿を見つけて解決しました。

今は画像のようにマウスと併用していますが、持ち運んでいるときなどはタッチパッドに切り替えて使うこともできます。

画像がブランクになると電源が切れる

NexDock2の電源はHDMI入力に連動しているので、ラズベリーパイの画像出力が止まると電源が切れます。 通常の接続では、ラズベリーパイの電源はNexDock2から供給されるので、ラズベリーパイの電源も切れます。 しかもよりによって、ラズベリーパイのスクリーンセーバーの初期設定は、画像出力をオフにする事になっているようです。 この組み合わせのせいで、ラズベリーパイをしばらく放置していると電源が切れている事がよくありました。

これは画像の出力がオフにならないようにすることで解決できます。 自分はxscreensaverをインストールしてスクリーンセーバーをオフにしました。

その他

あいにく自分の使っているスマートフォンは外部モニタに対応していないのですが、HDMI出力のあるものなら大概接続できるはずです。 USBで電源供給できるものなら、モバイル化するのも容易です。

たとえば、メガドラミニをつなげば、どこでもメガドラミニが!

f:id:uzusayuu:20200607152605j:plain

まとめ

癖があるので万人におすすめするものではありませんが、NexDock 2はなかなか面白いデバイスです。

特にラズベリーパイ4と接続する際は

  • config.txtの設定で、接続に必要なUSBケーブルの本数を一本にする
  • Micro HDMI to HDMIのケーブルにかえる
  • とりまわしのしやすいUSB Type-C ケーブルにかえる
  • xscreensaverを導入するなどして、画像出力がブランクにならないようにする
  • Fn+ESCを使って、不要なときはタッチパッドをオフにする

といった方法で、使い勝手を向上させる事ができました。

*1:ちなみに対応スマートフォンとの接続にはUSB Type-Cケーブル一本ですみます。

RISCVエミュレータ-ELFファイルの実行

はじめに

前回前々回のエントリーの続きです。

ゆっくりとRISCVエミュレータを作っています。

命令の追加

RV32Iの命令の殆ど(SRETとWFI以外)を処理できるようになりました。 ただし、システムレジスタ系の命令(CSRR*)は、読み書きはできるものの内部状態は実装されていません。 同じ理由でMRETも、権限の変更は行いません。

システムコールエミュレーション

ECALL命令ではシステムコールのエミュレーションを実行します。今実行できるのは以下の2つです。

システムコール 番号 処理
exit 93 終了
write 64 ファイルへの書き出し

fstat等の実装がまだなので、writeが出力するのは標準出力だけです。

ELFファイルの読み込み

簡単なELFファイルを読みこんで実行できるようになりました。 これで普通のC言語でRISCVプログラムを書いて、GCCでクロスコンパイルして、RISCVエミュレータで実行する事ができます。

RISCV用のクロスコンパイル環境はriscv-gnu-toolchainを使用しました。

github.com

実行できる命令が限られているので、このエミュレータ用のコンフィギュレーションにするには、toolのビルドのときに、

./configure --prefix=/opt/riscv --with-arch=rv32i --with-abi=ilp32

を指定して、I命令とILP32のABIを指定する必要があります。

これで、例えばこんなCプログラムが実行できます。

#include <unistd.h>

int main()
{
  write(1, "Hello, RISCV\n", 13);
  return 0;
}

コンパイルするときはriscv用コンパイラを使って、RV32IとILP32を指定して、ライブラリを静的にリンクする必要があります。 例えばこうなります。(gccにパスが通っている前提です。)

$ riscv32-unknown-elf-gcc hello.c -o hello -Wall -march=rv32i -mabi=ilp32 -static

これでhelloという名前のELF形式実行ファイルが作られます。

ちなみに-Sオプションをつけてコンパイルするとこんなアセンブラコードになります。

        .file   "hello.c"
        .option nopic
        .attribute arch, "rv32i2p0"
        .attribute unaligned_access, 0
        .attribute stack_align, 16
        .text
        .section        .rodata
        .align  2
.LC0:
        .string "Hello, RISCV\n"
        .text
        .align  2
        .globl  main
        .type   main, @function
main:
        addi    sp,sp,-16
        sw      ra,12(sp)
        sw      s0,8(sp)
        addi    s0,sp,16
        li      a2,13
        lui     a5,%hi(.LC0)
        addi    a1,a5,%lo(.LC0)
        li      a0,1
        call    write
        li      a5,0
        mv      a0,a5
        lw      ra,12(sp)
        lw      s0,8(sp)
        addi    sp,sp,16
        jr      ra
        .size   main, .-main
        .ident  "GCC: (GNU) 9.2.0"

こちらが実行結果です。

$ cmake-build-debug/RISCV_Emulator hello
Elf file name: hello
This is an Elf file
Program Header 0:Type: LOAD. Copy to 0x10000 from 0x0, size 5270. 
Memory size extended to 100000
Loaded
Program Header 1:Type: LOAD. Copy to 0x12498 from 0x1498, size 2132. Loaded
Section .bss found at 0x01cec.
Secure BSS.
Entry point is 0x10090
Section .symtab(2) found at 0x01d1c.
Number of symbols = 92, (1472 bytes)
Section .strtab found at 0x022dc.
Symbol "__global_pointer$" found at index 34.
Global Pointer Value = 0x12ca8.

Memory size extended to 800000
Execution start
Hello, RISCV
Return value: 0.

いろいろエミュレータが生成したメッセージに紛れていますが、最後に"Hello, RISCV"と表示されています。成功です。

この例ではwrite以外のシステムコールを使わずに済むように、write()を使って出力させましたが、printf()でも動作するようです。

RISCV-TESTSの実行。

前回のエントリでも触れましたが、RISCVにはRISCV-TESTSという名前の標準テストがあります。

github.com

このテストのうち、rv32ui(RV32ユーザーレベル、整数命令のみ)を実行してみたところ、LH命令にサイン拡張のバグが見つかりました。

テスト重要ですね。

他にも何個か見つかったバグを修正し、すべてのテストがパスするようになりました。

まとめ

RISCVのエミュレータC++で書いて、簡単なプログラムのELF形式実行ファイルを処理できるようになりました。

また、RISCV-TESTSのユーザーレベル整数命令テストをパスすることを確認しました。

このエミュレータのコードは私のgitリポジトリで公開しています。

github.com