別シリーズに (93) (94) (95) とRISC-Vのアセンブラねたを仕込んでしまいました。一応、アセンブラは「こちら」というこで引っ越しをすることにいたしました。今後はRISC-Vのアセンブラねたはこちらということでお願いいたします。ま、どちらでも大した違いはないんでありますが。しかし、何か月ぶりのシリーズ再開だ?
※「ぐだぐだ低レベルプログラミング」投稿順indexはこちら
まずは、アイキャッチ画像に、アセンブラを動かすための「お手軽でお買い求めやすい」マイコンボードSipeed Longan nanoと、これまた「お手軽でお買い求めやすい」デバッグI/F、RISC-Vデバッガを接続したところを掲げました。「鳥なき里のマイコン屋(95)」の後の方に掲げた「接続」写真からすると、
スッキリ
した感じ、お分かりでしょうか。途中の御見苦しい手配線の「アダプタ」を無くし、RISC-VデバッガをLongan nanoに直結してみました。これで
- JTAGを使ったデバッグ
- USART(UART)使ったシリアルモニタ
の両方を同時に使うことができます。そして、横に見えます1本のジャンパ線、
- RST信号
も接続いたしました。これで以前、USBからDFUモードにてバイナリをLongan nanoに書き込むために、ボタン2つをコチョコチョ押したり離したりする「儀式」もなくなりました(ボタン小さいので不器用な私には向いてなかった。)今はいつでもJTAG経由でダウンロードでき、そしてRSTかけて開始することができます。
さて本題。前回まで、簡単なアセンブラのソースプログラムを書いて、RISC-VのABI(アプリケーション・バイナリ・インタフェース、アセンブラ関数を呼び出すためのお約束)を触ってみました。そんな中で思うのは、
RISC-V、RISCだし、命令ニーモニック少ないし
記憶力が乏しい私メとしては歓迎すべき性質ではあるものの、x86(こちらは屋上屋を重ねた巨大な命令セットで有名なCISCでありますが)などと比べると直ぐに気付きます。
- MOV(転送命令)がない
- 即値のレジスタへのロードがない
まあね、細かくみると無いもの結構一杯あるんでありますが、MOVすらないのは困らないか?でもね、RISCーVの人はちゃんと考えてあるのでした。「疑似命令」と書くと、言語プロセッサとしてのアセンブラに指示を出すための、「機械語にならない」命令ですが、機械語に翻訳される「疑似」ニーモニックとでもいうべきものが定義されているのでした。ありがちですが
nop という命令は無いのだが、nopと書けばnop相当の命令が生成される
です。
- mv でmove(転送)
- li で即値のロード、load immediate
実際にコードを書いてみます
nop addi x0, x0, 0
上の2命令を objdump -d (勿論、RISC-V用の)でディスアセンブルしてみると
8: 0001 nop a: 0001 nop
どちらも nop になりました。つまり nop == addi x0, x0, 0 です。他のレジスタを使っても同等の操作になりそうですが、x0はzeroレジスタで、ここへの代入はなんでも飲み込むブラックホールのようなものらしく「ちょっと特別」らしいので、x0であるべきなようです。
お次は、
li t0, 33 addi t0, zero, 33
ロード・イミディーエイト、t0レジスタに即値33というもの。
c: 02100293 li t0,33 10: 02100293 li t0,33
やはり、ディスアセンブルすると、同じものになりました。zeroは先ほども出てきたx0レジスタで、0に33を足したものをt0に入れれば、t0に33をロードしたのと一緒、というカラクリ? zeroレジスタ大活躍です。
さてその次は、MOV(インテル式、MOVEならモトローラ式)、RISC-Vではニーモニックも短く mv
mv t1, t0 addi t1, t0, 0
これで、両方 mvになってくれれば。
14: 8316 mv t1,t0 16: 00028313 mv t1,t0
あれれ、ディスアセンブルしたニーモニックとオペランドは一致しているのに、アセンブルしたオブジェクトコードの長さが違う。なんで?
いやいやRISC-V、一筋縄ではいかないな。。。
鳥なき里のマイコン屋(95) Longan nano、RISC-Vデバッガ へ戻る