福野泰介の一日一創

かわいく思えるようになったx86マシン語、深みにハマって行き着いた「アセンブラ短歌
57577の5行、31byteで動くマシン語で、2byte以上の命令が行をまたいではいけないというストイックなルールが良い!

一句詠んでみました。

68 57 61 6B 61 31 C0 68 6D 62 6C 79 68 41 73 73 65 89 E1 6A 0C 51 6A 01 50 B0 04 CD 80 EB E1

タイトル「WakaAssembly...」 (x86/macOS Mojabe 32bit)

コンピューターの凄さを一番すぐに感じられるのは、繰り返し。 人間では不可能な速さで正確無比に繰り返される様を見せつけ、それが自分の指示によるものだと体感したものを虜にしてしまう。 (参考、IchigoJam BASIC のプログラム、RUN on IchigoJam web by WebAssembly

10 PRINT "WakaAssembly"; 20 GOTO 10

アセンブラ和歌アセンブラ和歌と繰り返しから誕生した、WakaAssembly、WebAssemblyっぽくて輸出しやすいかも。

CatalinaにOSアップデートで動作しなくなってしまう、macOS最後の32bitアプリの記念に。

x86マシン語(アセンブリ言語)で書かれたソースはこちら

00000000 <_main>: 0: 68 57 61 6b 61 push 0x796c626d 5: 31 c0 xor eax, eax ; eax = 0 7: 68 6d 62 6c 79 push 0x65737341 c: 68 41 73 73 65 push 0x616b6157 11: 89 e1 mov ecx, esp 13: 6a 0c push 12 ; length 15: 51 push ecx ; buffer 16: 6a 01 push 1 ; stdout 18: 50 push eax ; dummy 19: b0 04 mov al, 4 ; sys_write 1b: cd 80 int 0x80 ; syscall 1d: eb e1 jmp _main

pushで一度に4文字分、直接詰めるのがさすがCISC!jmp _mainで先頭へジャンプし、繰り返すたびにスタックを積み続けるので Segmentation faul を出してちゃんと止まり、現代OSのありがたみを感じる。(bits 32 として、32bitモードでのアセンブルが必要)

行儀よく、スタック位置を合わせ ret で 0 を返して終わるバージョン main-1shot.s、31byteのバイナリを和歌表示するために作ったミニプログラム wakaout.c もあります。
詳しくは「x86asm/wakaasm src on GitHub」で!

links
- アセンブラ短歌 - 坂井弘亮 / slideshare
- 「オープンソース」を使ってみよう (第33回 アセンブラ短歌)
- 31バイトでつくるアセンブラプログラミング ~アセンブラ短歌の世界~ Kindle版
- 「57577」の機械語を詠む「アセンブラ短歌本」まとめ - Togetter
- 根っこは同じ! Z80経験者によるx86マシン語はじめ、512byte bootBASIC をmacOS用に移植

マシン語秘伝の書を片手にx86マシン語入門が楽しい。Z80と8086のレジスタ対応表、根っこが同じと分かれば怖くない。 どちらの設計にも深く関わる、嶋正利さん

512byteのブートセクターに収まりブートする、x86マシン語で書かれた「bootBASIC」を発見! 世界最小のチェスプログラムの作者でもある、nanochessさんによる著作「Programming Boot Sector Games (PDF ver.)」を片手に、x86の入門として、16bitのリアルモード向けのbootBASICをmacOSの32bitアプリへと移植。


パスカルの三角形が動いた!


bootBASICは、使える命令も最小限、マルチステートメントもなしのシンプルなBASIC。固定メモリを使っていた元のコードを .data セクションに移して、si/diを32bit化したesi/ediに変更、BIOSの代わりに syscall を使う形にしてできあがり。 アセンブリ言語を使った開発は、アセンブラ nasm によって瞬時にバイナリ化され、即動作。スピード感が気持ちいい。


「Pascal's Triangle」 RUN on IchigoJam web
bootBASICの構文は、IchigoJam BASICにも使えるので、サンプルのプログラムそのままで動いた、パスカルの三角形!


bootBASIC_32bit src on GitHub
現在、Mac用のみ。


Programming Boot Sector Games (PDF ver.)」
1KBの半分、512byteにコンパクトに収めるためのマシン語の基本や、テクニックなど丁寧に解説された本がステキでした!

32bit化でEが付き、64bit化してRが付きと拡張されはしてますが、8bitの名機Z80(1976年)や、16bitアーキテクチャーの王様8086(1978年)の面影、しっかり残ってます。

Z80マシン語でブイブイいわせた人、最近の重量級開発環境が苦手な人、言語の流行り廃りに疲れた人、アセンブラによる超軽量開発で、マシン語でしか到達できない世界を切り開くとかどうでしょう?

links
- 41年経った今でも使える、いにしえのx86マシン語AAAをMacで動かす
- x86 - Wikipedia
- x64 アセンブリーの概要 | iSUS

Intel 8086から現代のCore iシリーズまで、脈々と続くx86アーキテクチャ。実は、誕生1978年と私と同い年。RISC-Vのシンプルさと合わせて引き合いに出される古の命令「AAA」を動かしてみました。


参考図書「8086マシン語秘伝の書 単行本 – 1990/10 by 日高徹氏、青山学氏
MSXでマシン語を使ってみたくて買った「Z80マシン語秘伝の書」の8086版! 16bit CPUである8086向けに、変更、セグメントなどx86ならではの項目が追加されている。Z80同様、古典と思いきや、普通に現代のMacでも普通に使えてしまうことに驚きます。

AAA命令もちゃんと載ってました!
2進法/16進法が基本のコンピューターと、10進法が基本の人をつなぐ命令の一つ。0から15までの数を2byte2桁表現にしてくれる便利命令でした。(src on GitHub)

_main: mov eax, 0 main_loop: push eax clc ; reset carry flag AAA call putnumhex pop eax inc eax cmp eax, 16 jne main_loop mov al, 0 ret

こちら実行結果

0000 0001 0002 0003 0004 0005 0006 0007 0008 0009 0100 0101 0102 0103 0104 0105

こちら0から15までをAXレジスタにセットして、AAA命令を通した結果です。確かに2byteになってくれると表示しやすくて便利です。

このような基本的な部分は一度作ってモジュール化してしまえば、再度作る必要はないので、専用の命令はリソースの無駄になります。 実際、x86アーキテクチャでも64bit環境ではAAA命令は削除されているので、上記プログラムは32bitモード(-f macho32)でコンパイルしています。(syscallの呼び出し方も違うので注意!)


こちら、8086マシン語秘伝の書から、144倍するという定数による掛け算を分解してする高速化するテクニック(main.s src on GitHub

SHL AX, 1 SHL AX, 1 SHL AX, 1 SHL AX, 1 MOV BX, AX SHL AX, 1 SHL AX, 1 SHL AX, 1 ADD AX, BX

144倍=128倍+16倍であることを利用して、シフトと足し算命令を使って実現しています。8086には掛け算命令MULがあるにも関わらずなぜこのテクニックが必要だったか?

秘伝の書記載の仕様によると、16bitの掛け算(MUL)にかかるクロック数はなんと118〜133。1bitシフト(SHL)も9クロックかかるとはいえ圧倒的に速いわけです。 現代CPUは掛け算も足し算も1クロックで終了するので、このテクニック自体は不要です。

そういえば、なぜわざわざ1bitずつシフトしているのでしょう?

SHL AX, 4 MOV BX, AX SHL AX, 3 ADD AX, BX

と書けばもっと短く、高速です。実は、この元になったZ80マシン語秘伝の書でも同じ内容があって、Z80には1bitシフトしかないので、ベタ移植したままになってしまったと想像。(追記、・・・違いました。8086にはイミディエイトのシフトは1限定。上記は80186から加えられた命令でした。 thanks! > @fujitanozomu

MOV CL, 4 SHL AX, CL MOV BX, AX MOV CL, 3 SHL AX, CL ADD AX, BX

8086命令を使って、このように書くこともできますが、2クロックで終わる1bitシフトと比較し、CLを使ったシフトは 8+4N クロックと遅く、速度を取るなら秘伝書記載の通りが正解でした。

コンピューターの特性を知り、いかに活かすか、今でも大事な基本ですね!
普段使っているCPUに近づくマシン語の世界、こちらのサンプルや入門をどうぞ!(x86asm src on GitHub

links
- 日本人が創ったCPUの歴史、MacのCPU Intel 64 マシン語はじめのいっぽ
- ハンドアセンブルで高速計算! RISC-V、RV32ICエミュレーターのC言語実装
- はじめてのマシン語 - IchigoJamではじめるArmマシン語その1

人気のArmマシン語入門の「つぎのいっぽ」ハンドアセンブルをRISC-Vでやってみました。


参考図書「RISC-V原典 オープンアーキテクチャのススメ | デイビッド・パターソン, アンドリュー・ウォーターマン, 成田 光彰
著者、デイビッド・パターソン氏は、RISC生みの親!

せっかくなのでハンドアセンブルしやすく実行効率の良い、16bitの圧縮命令拡張RV32Cを使いたいので、以前使用したエミュレーターにC拡張を勉強ついでに追加実装。(rv32emuの元、TinyEMUはC対応してます)

R11=0 R11+=R10 R10-=1 IF R10 GOTO -2 R10=R11 RET

RISC-VのC言語呼び出し規約では、R10が第一引数で返り値となり、R11も一時レジスタとして使用可能なので、R10/R11を使用。C拡張の命令のみを使ってasm15r表記で作成。

比較のためにこちらがArm Cortex-M0用、asm15表記ですが、ほぼ同じですね。

R1=0 R0=R0+R1 R0=R0-1 IF !0 GOTO -2 R0=R1 RET

RISC-Vにはフラグがない代わりに分岐命令で比較が可能です(比較した結果を0か1かで代入する命令でキャリーフラグを代用できます)。 足りない命令は、32bit命令を使えばOKなので、割り切ったコンパクトな設計が美しい。

RV32C RISC-Vマシン語表」を見ながらハンドアセンブルします。

0b0010010110000001, // R11=0 0b1001010110101010, // R11+=R10 0b0001010101111101, // R10-=1 0b1111110101110101, // IF R10 GOTO -2 0b1000010100101110, // R10=R11 0b1000000010000010, // RET

こちらを emu-rv32i-test-c.c で、仮想RAMに書き込んで、実行!
繰り返し足し算するプログラムが動きました!(src on GitHub


ArmのThmubと違って、C拡張はハードウェアで実装する別名的扱い。 よく使われる命令に絞って実装されており、32bit命令と併用できるのが特徴。たった400ゲートで実装できると言うだけあって、C言語での実装も約200行とコンパクト。(関数 convert_insn_from_c / src on GitHub

16bit命令を使うことで30%ほど容量が削減できて、ArmのThumbとほぼ近いサイズくらいになります。レジスタを複数PUSHするなどの命令を削減したため、より小さくはなりませんが、ハードウェアコストや実行性能にメリットあり。後発優位でもありますが、この辺りのバランス感覚が気持ちいい。

64bit時代にプログラムの容量削減に意味はあるのか?大有りなのです。メモリとのアクセスは時間がかかるので、何段ものキャッシュを使って実行効率を上げている現代CPU、命令がコンパクトになるとその分キャッシュヒット率が向上し、速く動作するわけです。実行時間=電力消費量=コストなので、省エネ化にもつながります。

RISC-V原典、一番おもしろかったのはV(ベクトル)拡張。CPU+GPUの歴史が変わりそう!V実装のフィックスと実CPUの広まり、大いに楽しみです。
(参考、RISC-Vベクトル拡張について解説する - Fixstars Tech Blog /proc/cpuinfoArm64のSIMD

理研のスパコンに使われたり、格安ハードが登場した2019年のRISC-V。今年もかなり伸びそうな予感のCPU、RISC-V(リスク・ファイブ)。RISC-V版Androidや、RISC-V版ノートパソコンの発売もあるかも?

RISC-Vは、由緒正しいハーバード大生まれのRISCアーキテチャーの第五世代。ライセンスフリーで自由に利用できるオープンかつ時代に合わせたチューニングによるハイパフォーマンスが特徴です。 以前32bit版で紹介しましたが、短くシンプルな16bitの縮小命令RV32Cを使って、Arm Cortex-M0学習用のasm15をRISC-Vに対応させたasm15rを設計。

そもそも、コンピューターとは何でしょう?
コンピューターとは、膨大な数を記憶し、正確かつ超高速に計算するものです。

どう記憶し、どう計算するかを指示する数、それがマシン語。 CPUが違えばマシン語が違います。各メーカーによって系統があり、具体的なCPUによって使える命令が異なりますが、基本的はどれも一緒です。


RV32C RISC-Vマシン語表 (asm15r)
こちらまとめたRISC-Vマシン語です(抜粋)
RISC-Vのラインナップは、32bit/64bit/128bitの大きく三種類。今回は入門しやすい32bitで縮小命令、掛け算割り算命令対応版をセレクト。

32bitコンピューターでの記憶は大きく2種類。数個から数十個ある32bit(4byte)のレジスタと呼ばれるものと、数KBから数GBまでのメモリ(RAMやROM)と呼ばれるもので記憶します。 RISCアーキテクチャでは計算はレジスタを使って行い、メモリとレジスタとのやり取りは別の命令で行います。


こちらがメモリとレジスタをやりとりする命令。

ここでRISC-Vを使った超シンプルなRISC-V 32bitコンピューターを仮定します。
1. メモリはアドレス0から始まる32byteのROM(16bitずつ16セットのスイッチで0/1切り替え可能、上下8bit入れ替え)
2. アドレス32から始まる4byte(32bit)には、対応する32コのLEDがついている(エンディアン入れ替え)
3. アドレス0から始めるリセットボタン

この架空のRISC-Vコンピューターに1+1を計算させるプログラムを上記asm15rを使った組みます。

R10=1 R10+=1 R11=32 [R11]=R10

メモリアクセスにレジスタR8以降しか使えないので、計算もレジスタR10とR11を使うことにします。


他にも、コンピューターにおいて大事な分岐や、複雑な計算の一時記憶に便利な機構スタックを実現する命令などが定義されています。

計算が終わった後もどんどん次のメモリを命令として実行していってしまうので、GOTO命令を使ってはじめに戻してあげましょう。

R10=1 R10+=1 R11=32 [R11+0]=R10 GOTO -4

この5つ、20byteの命令を命令表を見ながらビット列に置き換える、ハンドアセンブルし、スイッチを設定。(この作業を自動化するソフトがアセンブラやコンパイラ)

001 0 01010 00001 01 :'R10=1 000 0 01010 00001 01 :'R10+=1 001 1 01011 00000 01 :'R11=32 110 000 011 0 0 010 00 :'[R11+0]=R10 101 1 1 11 1 1 1 100 1 0 1 :'GOTO -4

これでLEDの右から2つ目だけが光って、1+1の計算結果が2であることを出してくれるプログラム、完成です!
スイッチをいじって、2+1の計算などにしてみましょう。

この架空のコンピューター、作ってみたくなりますね!
RISC-Vは誰もがオープンに使えるアーキテクチャ、また本ブログもCC BYのオープンデータ、自由に作って遊んだり売ったりして、OKです!

Armは、スマホや、IchigoJam、開発中の日本のスパコン富岳など、世界で最も普及しているCPUアーキテクチャ。Armの一番シンプルなCortex-M0のマシン語と比較してみましょう。

Cortex-M0 Armマシン語表 (asm15)
こちらも16bitが基本、似てますね。RISC-Vの縮小命令は32bitの標準命令と下位2bitで区別できるので混在できるのが特徴です。(RISC-Vの縮小命令には掛け算割り算がないので、32bit命令を使用)

Cortex-M0はレジスタ16本(プログラムカウンター含む)、RISC-Vは32本(内R0は0固定、プログラムカウンターは別)など、細かな違いの理由に思いを馳せるのもまた一興。

IchigoJamで、いますぐ遊べるマシン語の世界もぜひどうぞ!
はじめてのマシン語 - IchigoJamではじめるArmマシン語その1

LPC1114やラズパイで動く IchigoJam が対応しているマシン語は、Arm Cortex-M0 の16bitが基本のThumb命令。 マシン語表を見れば一目瞭然、とってもシンプルで使いやすい!

C言語でArm Cortex-M0を真似る(エミュレーション)プログラムを作り、IchigoJam web に組み込んでみました。

年賀アプリ2020のマシン語版を動かしてみた様子。


こちらArmマシン語入門から「画面をイチゴで埋め尽くす12の方法

これで実機でなくてもマシン語の世界に触れられます!
ただ、圧倒的なスピードを感じられないので、引き続き実機で触れるのが一番です。

まだ作りがいい加減なので、実機と挙動が違うところが多々あるはずです。
オープンライセンスなオープンソースなので、ご興味ある方、気軽にコミッターとしてご参加ください!
IchigoJam/acm0emu: CPU emulator for Arm Cortex-M0
組み込み簡単、とってもシンプルなC言語ヘッダー1ファイル、わずか700行あまり。
おかしな挙動のご報告(issues)や、テストコード寄稿も大歓迎です。

一日一創、デザインをシンプルに見やすくプチリニューアル。
鍵は、HTML viewportの幅指定。

<meta name="viewport" content="width=650">

iPhoneからの見た目、いい感じになりました。

HAPPY 2020 あけましておめでとうございます!
今年のプログラミング初めはマシン語で、7セグエミュレーション。

IchigoJam ver 1.4.1 実機での動作比較。BASICでもまぁまぁの速さですが、左から徐々に書き換わるところが目でも追えてしまう程度。対して、マシン語版は瞬時に切り替え、キビキビ動きます。

今年18年目を迎える株式会社jig.jp、社名の由来は「軽快」を辞書で探して見つけた単語「軽快なテンポで踊るjigダンス」に、日本発の意気込み加えた「jig.jp」。 原点は34年前から始めたプログラム、もっと快適に、もっと速く、もっと便利に。より豊かな社会の実現への探求は続きます。

一日一創 2020
今年もよろしくおねがいします

7セグエミュレーション、マシン語化メイキング

BASICのカウントダウンプログラムから、マシン語化する部分を決める

95 FORI=0TO7:[I]=0:NEXT 100 IFN&1[0]=[0]|#38 101 IFN&2[1]=[1]|4:[2]=[2]|4:[3]=[3]|4 102 IFN&4[5]=[5]|4:[6]=[6]|4 103 IFN&8[7]=[7]|#38 104 IFN&16[5]=[5]|#40:[6]=[6]|#40 105 IFN&32[1]=[1]|#40:[2]=[2]|#40:[3]=[3]|#40 106 IFN&64[4]=[4]|#38 107 IFN&128[2]=[2]|1:[5]=[5]|1 110 FORI=0TO7:POKE#700+I+M*8,[I]:NEXT

パラメータのセグメントを表すNと、書き換えるキャラクターを表すMをマシン語ルーティーンに渡す方法を決めます。 マシン語はPCG領域の始めの方を空けて、#740からスタート。192byteまでのマシン語が入ります。

U=USR(#740,M<<8|N)

RAMのアドレスR1を計算して、PCGをメモリアクセスを使って初期化(参考、マシン語入門その5

R2=R0 R3=8 R2>>=R3 R3=3 R2<<=R3 R1=R1+R2 R2=7 R3=8 R2<<=R3 R1=R1+R2 R2=0 [R1+0]L=R2 [R1+1]L=R2

100行のBASICのプログラムのマシン語化、Nの1ビット目を判定して、メモリを書き換えます

R2=1 R0&R2 IF 0 GOTO @SKIP0 R3=#38 R4=[R1+0] R4|=R3 [R1+0]=R4 @SKIP0

この調子で7+1セグメント分作ります(asm15ソース全文

レジスタR4は元に戻すルールなので、PUSH {R4,LR} ではじめて POP {R4,PC} で終わる、Armマシン語の定石。

できたアセンブリ言語のプログラムをハンドアセンブルか、asm15を使ってマシン語を生成して、プログラムへ組み込みます。
サクサクバージョンのできあがり!

10 POKE#740,16,181,2,70,8,35,218,64,3,35,154,64,137,24,7,34,8,35,154,64,137,24,0,34,10,96,74,96,1,34,16,66,3,208,56,35,12,120,28,67,12,112,82,0,16,66,9,208,4,35,76,120,28,67,76,112,140,120,28,67 20 POKE#77C,140,112,204,120,28,67,204,112,82,0,16,66,6,208,4,35,76,121,28,67,76,113,140,121,28,67,140,113,82,0,16,66,3,208,56,35,204,121,28,67,204,113,82,0,16,66,6,208,64,35,76,121,28,67,76,113 30 POKE#7B4,140,121,28,67,140,113,82,0,16,66,9,208,64,35,76,120,28,67,76,112,140,120,28,67,140,112,204,120,28,67,204,112,82,0,16,66,3,208,56,35,12,121,28,67,12,113,82,0,16,66,6,208,1,35,140,120 40 POKE#7EC,28,67,140,112,76,121,28,67,76,113,16,189 RUN NEW 10 S=1*60*60 20 VIDEO5:CLS:LC2,2:FORI=0TO4:?CHR$(224+I);:NEXT 25 LET[10],`111111,`110,`1011011,`1001111,`1100110,`1101101,`1111101,`100111,`1111111,`1101111 31 N=S/60/60:F=~S&1:M=0:GSB90 32 N=S/60%60/10:F=0:M=1:GSB90 33 N=S/60%60:F=~S&1:M=2:GSB90 34 N=S%60/10:F=0:M=3:GSB90 35 N=S%60:M=4:GSB90 40 S=S-1 42 WAIT60 50 IF S>=0 GOTO31 55 LET[20],`1110110,`1110111,`1110011,`1110011,`1110010 60 FORM=0TO4:N=[20+M]:GSB95:NEXT:WAIT60 61 LET[30],2,0,2,0:FORM=0TO3:N=[30+M]:GSB90:NEXT:N=0:M=4:GSB95:WAIT60 62 GOTO60 90 N=[N%10+10]+F*128 95 U=USR(#740,M<<8|N):RTN

links
- はじめてのマシン語 - IchigoJamではじめるArmマシン語その1

CPUの世界にもオープンデータ。オープンソースでオープンライセンス(BSDライセンス)なCPUアーキテクチャ「RISC-V(リスク・ファイブ)」の実機が続々登場! 1981年にバークレー大学から発表されたRISC-Iからスタートして5世代目のRISC-V、Google / NVIDIA / NXP / Qualcomm など、数多くの企業をメンバー企業に支えられて躍進前夜。

Amazonが発表した自社開発CPU、Graviton2はArmベースでしたが、次世代がRISC-Vになっても不思議はありません。(現時点でAmazonはまだメンバーではないが、オープンに誰でも使えるため、使用するのにメンバーである必要もない)

そんな RISC-V というオープンなコンピューターの気持ちになってみましょう!
IchigoJamで試した、はじめてマシン語Arm編のように、はじめのいっぽはハンドアセンブル!
Specifications - RISC-V Foundation(RISC-V仕様書 P130より)

Instructionsとは、RISC-Vというコンピューターができること一覧、基本は32bit(4byte)、メモリに書かれた命令にしたがって、どんどん計算していきます。 レジスタは基本32コ、そのうち0番レジスタX0は0固定。実行位置を表すプログラムカウンタ(PC)は別となっています。

ひとまず、1+1をさせてみましょう。
レジスタ同士の足し算は ADD (上の図の一番下)

ADD rd,rs1,rs2

rd = rs1 + rs2 という足し算をします。
RISC-Vは、32コあるレジスタ(X0-X31)の内、x10,x11...を引数や、返り値に使うことになっています(x10,x11は別名a0,a1)

ADD x10,x10,x11

こちらをマシン語表を見て、二進法32桁の数値に変換します。(RISC-Vのマシン語の基本は32bit、16bitの圧縮版もあります)

0000000 01011 01010 000 01010 0110011         rs2 rs1 rd

これを16進数に表すと

-> #00b50533

この4byteをメモリに書き込めばOKです!(RISC-Vは、little endian なので、#33,#05,#b5,#00 の順)

ただ、これだけではプログラムの終わりがわからずどんどんよくわからない計算が進んでしまうので、戻す(RETURN)命令を加えます。 RISC-Vでは、戻り先がレジスタ1番に入っているので、そちらへのジャンプ(GOTO)すればOK。 命令表の中から Brunch の JALR x1 を上記同様に16進数に変換します。(x1は別名ra)

JALR x1 (JALR rd,rs1) 0b00000000000 000001 000 00000 1100111         rs1 rd -> #00008067

できました!

実機で動かしてみたいところですが、今回は誰でも使えるエミュレーターを使います。

WebAssemblyにも対応し、ブラウザ上でRISC-V版Linux(JSLinux)まで動かしてしまうTinyEMUをベースにしたコンパクトなエミュレーターrv32emuを使います。

いろいろ組み込みに便利なようにコア部分を分離するように改造した rv32emu を作りました。
emu-rv32i.h をインクルードし、下記のように使います。

#include "emu-rv32i.h" #include <stdio.h> int main(int argc, char** argv) { uint32_t start = 0; ram_start = 0; uint32_t end = 0xfffffffe; *(uint*)(ram + start + 0) = 0x00b50533; // ADD x10,x10,x11 *(uint*)(ram + start + 4) = 0x00008067; // JALR x1 pc = start; reg[2] = ram_start + RAM_SIZE; // sp - stack pointer reg[1] = end; // ra - return adderss reg[10] = 1; // a0 reg[11] = 1; // a1 while (machine_running) { next_pc = pc + 4; insn = get_insn32(pc); printf("[%08x]=%08x\n", pc, insn); execute_instruction(); pc = next_pc; if (pc == end) break; } printf("x10 a0: %08x\n", reg[10]); return 0; }

結果はこちら

x10 a0: 00000002

見事、x10に 1+1 の結果、2が入っていますね!
reg[10]やreg[11]の初期値を変えたり、他の命令をハンドアセンブルしてみたりと、いろいろ試してみましょう。

MacでRISC-Vの開発環境を入れるなら、Homebrewを使うと楽ですよ!

$ brew tap riscv/riscv $ brew install riscv-tools

links
- はじめてのマシン語 - IchigoJamではじめるArmマシン語その1

結論、できる!
ただし、コンピューター自体の仕様であるマシン語へ都度翻訳する、インタプリタ型の IchigoJam BASIC では無理。

真の力を引き出す、マシン語と、プログラミング言語の世界をのぞいてみよう! for 福井高専電子情報工学科1年生。


IchigoJamのハーフキット、はんだづけからスタート!


つないで、LED1、光った!完成! (90分1コマちょっとでほぼ全員完成、はんだごての準備などをしておけば短縮可能、失敗した人用完成版もいくつかあるといい)


授業としてははじめてのプログラミング!


LEDが点滅するロボットの仕組み、かわくだりゲームによるアプリづくりの基本を小学生向けの3倍速で紹介!
IchigoJamは、本当に1秒に5000万回計算できるのか!? 〜IchigoJam マシン語入門〜(keynote/PDF)」
はんだづけから、はじめのいっぽ、ゲームづくりまでの資料はこちら!アレンジ自在のオープンデータ。
一度やったら大丈夫、きっと先生として小学生に教えられますよ!


IchigoJamは、本当に1秒に5000万回計算できるのか!? 〜IchigoJam マシン語入門〜(PDF)」
今回初公開、マシン語入門!かわくだりゲームまでやった人向け、小学生でもきっとOK!


100円のコンピューターがなんと1秒間に5000万回!・・・でも、本当に?


実際測ってみると、VIDEO0で表示を消してもせいぜい1秒に1000回・・・、遅い!
その理由は、IchigoJam BASICがインタプリタ型のプログラミング言語だから。


マシン語ではなそう!


IchigoJamのCPU、NXP LPC1114の説明書と、Armの説明書をまとめてできた、マシン語表


足し算は、Rd += u8 を使う!


2進数、10進数、16進数の変換は IchigoJam BASICのコマンドでも簡単!


マシン語をメモリに書き込んで、USRを使って呼び出し!(呼び出し元にかえる #4770 がないと、どうなっちゃう!?)


マシン語で足し算のループを作ろう!


1000回でも1万回でもCLTとTICK()では1/60秒未満で測定不能なので、ループ回数を100倍に!


ビデオ表示を消して、1ループ1000万回になった!プログラムとマシン語表のサイクルを見てみると、確かに1秒間に5000万回計算できてることが判明!


実は、CPUだけだと、最新のCPUでも、1つだけならたかだか40倍くらいしか変わらない。
3D計算やAIなど、特定の計算に特化したハードウェア(GPU)の活用が、圧倒的計算力を活かす鍵!


圧倒的パワーが魅力なコンピューター。いろいろたのしいものつくっちゃおう!


好評だったNT鯖江2019、来年のNT鯖江2020の開催は、2020/10/3-4が有力!
見に来るだけでももちろん歓迎、でも、せっかくなら、なにかつくって出展しよう!

links
- はじめてのマシン語 - IchigoJamではじめるArmマシン語その1
- 福井で初開催!なにかつくろう、NT鯖江2019! ダイジェスト動画と交互連打で目指せ世界記録ゲーム!

IoT人流センサーでも活躍、超音波で距離を測るセンサー「HC-SR04」は、デジタル入力を使ってアナログ量が測れます。
0か1かしかないデジタルでどうやって、量がわかるのでしょう?
1になるまでの時間を見るのです。

改めて、このセンサーの使うプログラムを見てみましょう。
(測距センサーHC-SR04:IchigoJam、Trig:OUT1、Echo:IN1、GND:GND、Vcc:5V)

10 OUT1,1:OUT1,0:A=0 20 A=A+1:IF IN(1) CONT ELSE ?A 30 WAIT 5:GOTO 10

OUT1としてしまうと、他のOUTポートもまとめてコントロールしてしまうので、OUT1,1:OUT1,0と変更しました。
これがセンサーのTrigとなり、超音波センサーの2つの丸めの1つから超音波のパルス(短い時間の1)が発射されます。
この超音波が返ってくるまでの時間を変数Aを使って、IN1が0になるのを待つ。Aが距離。
以上が使い方の基本です。

OUT1が埋まっている時は、TrigをOUT2から6まで空いているところに挿して、例えば10行をOUT3,1:OUT3,0とかすればOK!
IN1が埋まっている時は、EchoをIN2から4までの空いているところに挿して、例えば20行をIN(2)とかすればOK!

(測距センサーHC-SR04:IchigoJam、Trig:OUT3、Echo:IN2、GND:GND、Vcc:5V)

10 OUT3,1:OUT3,0:A=0 20 A=A+1:IF IN(2) CONT ELSE ?A 30 WAIT 5:GOTO 10

IchigoJamが速いほどに、近いものが認識でき、細かく測れます。高速化した1.4β、お試しください!

いろんなセンサーやモーターを組み合わせて、誰も作ったこと無いものつくっちゃいましょう!


HC-SR04 x IchigoJam S

更に、精度が必要な場合や、ファームウェアの書き換えが面倒な場合、マシン語を使って時間計測を高速化します。

R0=0 R1=[@IN3]L @LOOP R2=[R1]L R0=R0+1 R2-0 IF !0 GOTO @LOOP R0=R0>>9 RET @IN3 DATA L #50000080

IN1のアドレスは #50001000 でした。
IN2はアナログ入力設定になっているので切り替えが必要なため、少しややこしい。
IN3のアドレスは #50000080
IN4のアドレスは #50000100
となります。

これをasm15を使ってアセンブルするか、マシン語表を見ながらハンドアセンブルしてできるマシン語がこちら。

10 POKE#700,0,32,3,73,10,104,64,28,0,42,251,209,64,10,112,71,128,0,0,80 20 OUT1,1:OUT1,0:?USR(#700,0) 30 WAIT 5:GOTO 20

このアドレスの求め方、IchigoJamのCPU、LPC1114の取説によると、PIO0のベースアドレスは #50000000
IN3は、PIO0_5の場所なので ?"#5000";HEX$(1<<(5+2),4) → #50000080
IN4は、PIO0_6の場所なので ?"#5000";HEX$(1<<(6+2),4) → #50000100
(参考、マシン語でLEDを光らせよう! - IchigoJamではじめるArmマシン語その4


Hana道場、越前がにロボコンに向けて開発が進んでます!超音波センサーを違うポートで使いたい?


2つのモーター制御に、たまごを惑星においてくるためのサーボ制御、ライントレース用の2つセンサー、もりもりです!
これにレアメタル判定用に、超音波センサーを追加!


福井の小学生向けご当地ロボコン「越前がにロボコン」いよいよ今週末11/3開催
11/3日 9:00-17:00 ショッピングシティ ベル、あじさいホールにて!(Googleマップ

Tweet
クリエイティブ・コモンズ・ライセンス
この作品は「Creative Commons — CC BY 4.0」の下に提供されています。
CC BY 福野泰介 - Taisuke Fukuno / @taisukef / アイコン画像 / プロフィール画像 / RSS