福野泰介の一日一創 - create every day

My First Machine language - the simplest course of Arm machine language with IchigoJam step1

2018/01/25
#IchigoJam #KidsIT #Arm #rasppi #english 

Computers only know them binary machine language using just 0(off) and 1(on).
How do we make binary number sequence? It's depends on computers.


"RUN the Arm machine language on IchigoJam RPi after 1.2b16 (Raspberry Pi 2)"

The computer of IchigoJam understands 16 bit words (0 or 1 x 16).

0011000000000001

This machine language means to add 1 to R0 register. (resisters are kind of memories in the computer)

First 5 bit means "to add", next 3 bit means the resister number, last 8 bit means number to add.

00110 000 00000001

Let's write to RAM using POKE command of IchigoJam BASIC. (*IchigoJam BASIC reference ver 1.2)

POKE#700,`00000001,`00110000

#700 is position of RAM. Number starts with ` means binary number. (# for hexadecimal number)
To write last 8 bit in the first is a rule of this computer. (little-endian)

You need an other machine language word to work, "return" to IchigoJam BASIC.

0100011101110000

Write this word to RAM in the same way.

POKE#702,`01110000,`01000111

You are ready to run!

?USR(#700,1)

Did you get a number 2 as a right result?

USR command needs an start address of the machine languages and a number as a parameter.
Please check using 100 as a parameter.

?USR(#700,100)

Try to make to add 5 program using the machine language.

POKE#700,5 ?USR(#700,100)

You did it!

Speed is the greatest advantage of using the machine language.
The disadvantage is wrong machine language program doesn't protect your system.
So, please save before run if you make long program with machine language.

IchigoJam will stop if you write wrong machine languages.
Try to freeze your IchigoJam.

?USR(#704,0)

Computers work with some machine language words such them.
CPU of IchigoJam (LPC1114 Arm Cortex-M0) knows only 56 words Arm Thumb machine language.
It's very simple to understand!

If you use IchigoJam RPi after 1.2b16 (Raspberry Pi2/3 Arm Cortex-A7/A53), it knows more words.

It's a sample code to use SIMD(single instruction multiple data) machine language.
QADD8 can calculate 4 number as parallel during just 1 CPU cycle.

POKE#700,#80,#FA,#10,#F0,#70,#47 ?HEX$(USR(#700,#1234)) 2468

*It can calculate 8bit x 4 numbers but variables of IchigoJam BASIC are 16bit.

To be continued!

references
- Cortex-M0 Technical Reference Manual - Instruction set summary / ARM Information Center
- Cortex-A7 MPCore Technical Reference Manual - About the programmers model / ARM Information Center

links (now in Japanese)
- asm15 - simple Arm assembly language and machine language table
- asm15 assembler for IchigoJam
- series of "My First Arm Assembly language"

STM32はじめのいっぽ、64byteでつくるエルチカ1Hz Armマシン語

2017/12/24
#Arm #stm32 

CPUアーキテクチャとしてArmを採用しているメーカーはたくさんあるので、Armマシン語を覚えたらいろいろと応用できます。 今回コントロールするマイコンは、STマイクロエレクトロニクスSTM32F031K6です!


実は古い、STM32との出会い。マイコンに興味を持ち始めた4年前、開発環境が1,000円とあまりに安かったでひとまず買ってWindowsでデモのエルチカを見るも、Macでの開発環境が見つからずお蔵入り。 その後、書籍「組み合わせ自在!超小型ARMマイコン基板」をきっかけにNXP社のDIP版LPC1114に出会ったできた、IchigoJam

IchigoJamでマイコン開発で使っているDIP版LPC810も残念ながら生産終了なので、メーカー問わずマイコン探しをしている中での再会です!

ひとまず一番小さいSTM32F0シリーズのお手軽ボード「STM32 Nucleo Board STM32F031K6」で実験。 Arm Mbedに対応したUSBでPCに接続するとドライブとして認識して、binファイルをコピーするだけで書き込んでくれます。

LPC1114と同様、Arm Cortex-M0なので、基本は一緒。 親切な取説を見ながら、ひとまずミニマムなエルチカ(64byte)が完成! (参考、Cortex-M0 Armマシン語表(抜粋)

DATA L #20001000 ' stack top DATA L #08000009 ' entry point @ENTRY R0=[@RCC_AHBENR]L R1=[R0]L R2=1 R2=R2<<18 R1|=R2 [R0]L=R1 R0=[@GPIOB]L ' GPIOB_MODER R1=`01000000 [R0]L=R1 R0+=#14 ' GPIOB_ODR R1=`1000 R2=0 R3=[@WAIT_CNT]L @LOOP [R0]L=R1 R4=R3 R4-=1 IF !0 GOTO -1 [R0]L=R2 R4=R3 R4-=1 IF !0 GOTO -1 GOTO @LOOP @RCC_AHBENR DATA L #40021014 @GPIOB DATA L #48000400 @WAIT_CNT DATA L 1000000

RCC_AHBENRでGPIOを有効にする(省エネの基本は使う部品だけ有効に!)
GPIOB_MODERでGPIOを設定(Nucleoの取説より、PB3にオンボードLEDがつながっていることを確認)
GPIOB_ODRでGPIOに書き込む(メモリマップドI/Oなので、メモリに書き込むだけ)
空ループでWAIT(1ループ4clock、標準は8MHzなので、1Hzエルチカするには1万回でOK!)
* Flashは#08000000に置かれます。チェックサムがないので手抜きするとヘッダは8byteでOK!

asm15 Assemblyでstart address:0、hex fileにアセンブルして、objcopyでbinファイルを作って、コピーしてみましょう!

cat > obj.hex :1000000000100020090000080A480168012292043B :10001000114301600848402101601430082100228A :10002000064B01601C46013CFDD102601C46013CB0 :10003000FDD1F6E7141002400004004840420F00D2 :00000001FF arm-none-eabi-objcopy -I ihex --output-target=binary obj.hex obj.bin

定格いっぱいフルパワー48MHzでエルチカする方法はこちら

DATA L #20001000 ' stack top DATA L #08000009 ' entry point @ENTRY 'clock 48MHz R0=[@FLASH]L ' FLASH_ACR R1=[R0]L R2=`10001 ' 1<<4:enbale prefetch, 1 wait state R1|=R2 [R0]L=R1 R0=[@RCC]L R3=R0+4 ' RCC_CFGR R1=[R3]L R2=`1111 R2=R2<<18 R2=~R2 R1&=R2 R2=4 ' PLLMUL6 R2=R2<<18 R1|=R2 [R3]L=R1 R1=[R0]L ' RCC_CR R2=1 R2=R2<<24 ' PLLON R1|=R2 [R0]L=R1 R2=R2<<1 ' PLLRDY R1=[R0]L R1&R2 IF !0 GOTO -2 R1=[R3]L ' RCC_CFGR R2=2 ' PLL R1|=R2 [R3]L=R1 R2=12 R1=[R3]L R1&=R2 R1-8 ' 2<<2 == PLL IF !0 GOTO -3 ' init GPIO R0+=#14 'RCC_AHBENR R1=[R0]L R2=1 R2=R2<<18 R1|=R2 [R0]L=R1 R0=[@GPIOB]L ' GPIOB_MODER R1=`01000000 [R0]L=R1 R0+=#14 ' GPIOB_ODR R1=`1000 R2=0 R3=[@WAIT_CNT]L @LOOP [R0]L=R1 R4=R3 R4-=1 IF !0 GOTO -1 [R0]L=R2 R4=R3 R4-=1 IF !0 GOTO -1 GOTO @LOOP @FLASH DATA L #40022000 @RCC DATA L #40021000 @GPIOB DATA L #48000400 @WAIT_CNT DATA L 6000000

24MHzを超える場合はFlashアクセスにウェイトが必要です。ただプリフェッチバッファー4byteが3つあり、それを有効にしておくことで、速度はそこそこ保たれます。 PLLを有効にして、内蔵クロック8MHzを6倍にする設定をして、クロックを切り替えることで48MHz動作になります!エルチカも6倍速くなってしまうので、WAIT_CNTを6倍にして1Hzエルチカのできあがり!

次は、Nucleoの書き込み機能に頼らず、IchigoJamからマイコンへの書き込みに挑戦です!

links
- リファレンスマニュアル STM32F0x1/STM32F0x2/STM32F0x8 advanced ARM®-based 32-bit MCUs
- IchigoJamとLPC810でつくるLED点滅クリスマスアクセサリー
- はじめてのマシン語 - IchigoJamではじめるARMマシン語その1

Arm社訪問! クリスマスはArmマイコン IchigoJam を使ったオリジナルツリーづくりはいかがでしょう? Armマシン語 LPC810 x WS2812B 24MHz版

2017/12/19
#IchigoJam #KidsIT #lpc810 #asm #Arm 

Arm社の日本法人、アーム株式会社を訪問。Armと言えば、に、LPC810に、Z80以来のマシン語、楽しませてもらっています!(連載、Armマシン語入門
* 今年、2017.8.1、Arm社は、ARMからArmへと社名とブランドとロゴを変更(ロゴは全部小文字)。合わせて、本ブログ表記もArmへと変更しました。

内海社長ともお会いできました!クリスマスツリーの電飾は、おなじみWS2812B、Armでコントロールされたました!

おみやげに頂いた厚い本「ディジタル回路設計とコンピュータアーキテクチャ[ARM版]
スイッチサイエンスさんも翻訳出版に協力
原著はなんとKindleでも1万円オーバーの超大作「Digital Design and Computer Architecture: ARM Edition

なぜコンピューターは計算が速いのか?」で解説したスイッチの実体、トランジスタや2進数などの基本もしっかり。

マシン語、アセンブリ言語に関する解説もArmの実アーキテクチャーに添っていて実用的!

HDLや、具体的なCPU設計にまで踏み込むマイクロアーキテクチャの章まで揃っていて読み応え抜群。

サイトからI/Oや、C言語に関する解説などをpdfで読むことができます。
Elsevier · Harris, Harris: Digital Design and Computer Architecture · Welcome

2017.12.25(月)、クリスマス。Yahoo! Japan ロッジにて、Armマイコン、IchigoJamで作るクリスマスツリーづくりワークショップを復興庁さん主催で開催!

Fw:東北Weekly 家族でプログラミングしてみよう! 東北発のほやアートをつくってみよう! | Peatix
小中学生のこどもと保護者の方が対象です。プログラミングがはじめての人でもOK!自分だけのオリジナルキラキラツリーを作りましょうっ

(おまけ)Arm訪問記念マシン語プログラム for LPC810、24MHzで800kHz正確コントロール版。

DATA L #10000400 ' stack DATA L #21 ' entry point DATA L 0, 0, 0, 0, 0 DATA L #EFFFFBDF ' VALID_CODE = 0x100000000-0x10000400-0x21 @ENTRY R0=[@SYSAHBCLKCTRL]L R1=#DF 'SWM, GPIO, I2C:off, FLASH, FLASHREG, RAM, ROM, SYS [R0]L=R1 R0=[@FLASHCFG]L R1=[R0]L R2=3 ' flash no wait: set 0b00 R2=~R2 R1&=R2 [R0]L=R1 ' clock setting 24MHz R0=[@PDRUNCFG]L ' PLL power on R1=[R0]L R2=128 R2=~R2 R1&=R2 [R0]L=R1 R0=[@MAINCLKSEL]L R1=3 ' set PLL [R0]L=R1 R0=[@SYSPLLCTRL]L R1=1 ' 0:12MHz 1:24MHz, 2:36MHz, 3:48MHz, 4:60MHz, 7:96MHz, 8:108MHz NG [R0]L=R1 R0=[@MAINCLKUEN]L R1=0 [R0]L=R1 R1=1 [R0]L=R1 ' GPIO setting R0=[@PINENABLE0]L R1=[@PINENABLE0_DATA]L [R0]L=R1 R0=[@GPIO_DIR0]L R1=`1100 ' PIO0_2 and PIO0_3 [R0]L=R1 R4=[@GPIO_NOT0]L R2=`100 ' PIO0_2 ' WS2812B driver ' R0 - data count ' R1 - data address (G1,R1,B1,G2,R2,B2 ....) ' R2 - OUT value ' R3 - data value ' R4 - GPIO address ' R5 - bit count ' R7 - wait count @WS2812B R0=15 R1=@DATA_LED @LOOP_DATA R5=#80 R3=[R1] @LOOP_BIT [R4]L=R2 R3&R5 IF !0 GOTO @ONE @ZERO ' 10-20clock R7=2 ' wait 2*3 = 6clock R7-=1 IF !0 GOTO -1 NOP [R4]L=R2 R7=3 ' wait 3*3 = 9clock R7-=1 IF !0 GOTO -1 GOTO @JOIN @ONE ' 20-10clock R7=5 ' wait 5*3 = 15clock R7-=1 IF !0 GOTO -1 NOP [R4]L=R2 NOP @JOIN R5=R5>>1 IF !0 GOTO @SKIP2 ' 7clock == 1 R1+=1 R0-=1 IF !0 GOTO @LOOP_DATA GOTO @END @SKIP2 NOP NOP NOP GOTO @LOOP_BIT @END R7=[@WAIT_N]L R7-=1 'wait R7*3+1 clock IF !0 GOTO -1 GOTO @WS2812B ' init @SYSAHBCLKCTRL DATA L #40048080 @FLASHCFG DATA L #40040010 @PINENABLE0 DATA L #4000C1C0 @PINENABLE0_DATA DATA L #FFFFFFBF @GPIO_DIR0 DATA L #A0002000 @GPIO_NOT0 DATA L #A0002300 ' clock setting @MAINCLKSEL DATA L #40048070 @MAINCLKUEN DATA L #40048074 @SYSPLLCTRL DATA L #40048008 @PDRUNCFG DATA L #40048238 ' WS2812B @WAIT_N DATA L 4000000 @DATA_LED DATA B 10,0,0, 0,10,0, 0,0,10, 10,0,10, 0,10,10

正確に10clockと20clockに合わせているので、きれいな800kHzの波形がでているはず!
Flashのwait stateを0にしながら、24MHzが正しいのかはちょっと謎ですが、動いてはいるようです。
asm15 アセンブリ言語、アセンブルは、asm15 Assembler でどうぞ!

IchigoJam/Ichigolatteで使えるマシン語生成、アセンブリ言語&アセンブラ、asm15 on GitHub

2017/09/15
#IchigoJam #Arm 

ゲームづくりの醍醐味は、どういう仕掛けでプレイヤーを喜ばせようかとあれこれ考えること。 プログラミングすればすぐに実現。まずは自分が楽しめて、人に喜んでもらって二度美味しい!

ゲームづくりに慣れてくるとやってみたくなる複雑な仕掛け。複雑になればなるほど高速なコンピューターといえども、遅くなります。 そこを、いかに効率がいいロジックを考えるかが腕の見せどころ!IchigoJamでのゲームづくりは、限界が低い分、すぐにその成長のチャンスに巡り会えます。

アルゴリズム(=考え方、作り方)でなんとかするのが常套手段ですが、奥の手に「マシン語」があります。

IchigoJam BASICは、インタプリタといって、分かりやすく書かれたプログラミング言語をプログラムでコンピューターが分かる言葉「マシン語」にひとつひとつ翻訳しながら動く仕組みでできています。 もし直接「マシン語」で話せたら、翻訳者(インタプリタ)が必要ない分、速くなるわけです。

IchigoJamをお持ちであれば、すぐに試せるマシン語入門。
はじめてのマシン語 - IchigoJamではじめるArmマシン語その1

0と1の羅列であるマシン語を分かりやすくするためのアセンブリ言語。
初心者にもわかりやすい表記でつくったオリジナルのアセンブリ言語「asm15」としてまとめました。
Cortex-M0 Armマシン語表(抜粋)

Cortex-M0とは、Arm規格のCPUに要求される処理速度別のラインナップの内、最も遅い部類のシリーズ名です。 遅い代わりに、回路が小さく、省エネで、機能が少なくわかりやすいという大きな利点があります!

BoxHeadRoomさんが開発した、この「asm15」表記のアセンブリ言語をマシン語に変換するプログラム(アセンブラといいます)に足りなかった命令などを加えた「asm15 assembler」をGitHub上へのアップしました。
asm15 assembler for IchigoJam / IchigoLatte

まだ使い勝手が悪い部分や、足りない命令があります。
ぜひオープンオースプロジェクト「as15 on GitHub」にご参加ください!

電子工作マガジンの常連、田木屋商店さんのIchigoJam作品、ミサイル防衛ゲームや、落ちものゲームなどには効果的にマシン語が使われています。 まずは遊んで、改造して、少しずつ自分のモノにしていきましょう。

試しに、逆アセンブラを作ってみるのも楽しかも?
座学より体験、体験よりものづくり。ものづくりに勝る学習なし!

- 連載、IchigoJamではじめる、Armマシン語入門
1. はじめてのマシン語
2. ハンドアセンブルで超速計算!
3. マシン語メモリアクセスで画面超速表示!
4. マシン語でLEDを光らせよう!
5. 楽しさ広がるマルチバイトメモリアクセスとスタック
6. マシン語使いこなしTIPS
7. カジュアルに使うインラインマシン語
8. アセンブラを使って楽しよう
9. マシン語で高速SPI
10. マシン語を制するもの時間を制す
11. 画面をイチゴで埋め尽くす12の方法
12. レジスタ不足に上位レジスタとスタック操作

アセンブラを使って楽しよう IchigoJamでまなぶ Armマシン語入門その8 / Let's Use Assembler! Learning Arm Machine Language on IchigoJam

2017/05/15
#Arm #asm #IchigoJam 

ちょっと大きなプログラムをマシン語で作っていくとき、変更するたびに、ジャンプ先のアドレスを計算するのが面倒になってきます。そんな時便利なのがアセンブラというツール。いままでやってきた対応する命令を2進数コードにする作業(ハンドアセンブル)を自動化します。
"Assembler" is useful tool to make pretty big program written in machine language. Numbers of address to jump are calculated automatically!

マシン語入門その6でつくった、画面に大きく文字を表示するプログラムをアセンブラを使ってやってみました。
For example, BIG SCREEN program on part 6.

10 POKE#700,240,181,148,70,0,38,15,24,9,35,27,2,201,24,184,93,192,0,18,24,0,36,19,93,128,37,24,70,40,64,0,208,1,32,8,112,1,49,109,8 20 POKE#728,247,209,24,49,1,52,8,44,241,209,24,57,3,32,48,64,3,40,0,208,224,57,98,70,1,54,12,46,227,209,240,189 RUN OK A=USR(#700,"+IchigoJam+!"):WAIT120


"asm15 - Arm Cortex-M0 Assember for IchigoJam"

ふたつある同じレジスタ上の足し算は、 R1=R1+1 と R1+=1 と区別する形に変更したので注意!
Notice! I modified the code R1=R1+1 and R1+=1

やってみよう! Challenge
- 任意の場所に大きな文字を表示するプログラムをつくろう (BIG CHARs on any position)
- ハーフグラフィクスを使った文字表示プログラムをつくろう (middium chars using half graphics)

- 連載、IchigoJamではじめる、Armマシン語入門
1. はじめてのマシン語
2. ハンドアセンブルで超速計算!
3. マシン語メモリアクセスで画面超速表示!
4. マシン語でLEDを光らせよう!
5. 楽しさ広がるマルチバイトメモリアクセスとスタック
6. マシン語使いこなしTIPS
7. カジュアルに使うインラインマシン語
8. アセンブラを使って楽しよう
9. マシン語で高速SPI
10. マシン語を制するもの時間を制す
11. 画面をイチゴで埋め尽くす12の方法
12. レジスタ不足に上位レジスタとスタック操作

How to divide on IchigoJam Assembly

2017/04/28
#IchigoJam #asm #Arm #english 

About the machine language on IchigoJam, you cant't find how to divide (除算/割り算@ja) on the Arm Cortex-M0 command table. It's right. Arm Cortex-M0 has no commands of division. Instead you can use the function to divide.

IchigoJam BASIC command "USR" pass an address of function to divide as the register R3 after IchigoJam 1.2b31. (IchigoJam-FAN to download the latest version 1.2b45)

asm: R1=3 → 00100 001 [num]
asm: GOTO R3 → 010001110 [R3] 000
BASIC: PRINT 100 / 3 → 33

If you want to use the number as remainder (R1), call it!

[0]=`00100 001<<8 + 3 [1]=`1011010 100000000 [2]=`010001111 0011 000 [3]=`0100011000 001 000 [4]=`1011110 100000000 ?USR(#800,100) 1

asm: R1=3 → 00100 001 [num]
asm: PUSH {LR} → 1011010 100000000
asm: GOSUB R3 → 010001111 [R3] 000
asm: R0=R1 → 0100011000 [R1] [R0]
asm: POP {PC} → 1011110 100000000
BASIC: PRINT 100 % 3 → 1

Enjoy programming with the simple machine language!

links
- Cortex-M0 Armマシン語表(抜粋)
-
はじめてのマシン語 - IchigoJamではじめるArmマシン語その1
- IchigoJam-FAN on Facebook

バーチャルマシンにディスプレイを接続、avmで動かすIchigoJamマシン語

2016/10/01
#IchigoJam #js #Arm #avm 

決められた手順(プログラム)通りに、ひたすら高速に計算するだけの機械、CPU。
これに手足顔をつなぐことで、ゲーム機、家電、パソコン、ロボットになります。

前回つくった、ソフトウェアによるArm Cortex-M0風CPUシミュレーション。
これに人間の顔にあたる、ディスプレイをつなげてみました。


avm with display
[RUN]ボタンをおすと、レジスタを忙しく変化させながら、健気に計算しまくる様子をのぞけます。

プログラムやデータ、計算した結果を記憶する機能を担う「メモリ」。特定の場所(アドレスと言う)を表示すると決めれば、それが顔になります。今回接続したディスプレイは、IchigoJamと同じ仕様、アドレス0から256コ分のキャラクターパターン、16進数で900から32x24の768byteが表示するキャラクターコードにしています。

メモリが潤沢にあるパソコン上の仮想コンピューターなので、6.2Mbyteをディスプレイ用のメモリにして、1920x1080のフルHD、1画素にRGB256階調(3byte)対応に改造することも可能です。(参考、IchigoJamのメモリマップ

サンプルとして設定済みのプログラムは、IchigoJamではじめるマシン語その5「大きな文字を256倍速表示」で生成したマシン語です。 コンピューターへの理解を深める、マシン語学習のお供にぜひどうぞ!(deleyが1以上の時、JavaScriptのコンソールには、実行した命令を表示します。)

VMとしては不完全なので、C言語などで開発したArmマシン語を貼り付けても「not supported op」と出てスキップされます。必要に応じて改造ください。

楽しく制するマシン語、Armマシン語学習用VM on JavaScript

2016/09/27
#js #Arm #avm 

イマドキのBASICとしてIchigoJamが紹介サれている今月の「日経ソフトウェア」で見かけたマシン語の話題。 ドラゴンクエストのゲームデザイナー、堀井雄二氏はNEC PC-6001のBASICでプログラムを始め、速度を求めてZ80マシン語へ。ハンドアセンブルでマシン語プログラムを作ったそう。 「矢沢久雄のソフトウェアの基礎Q&A」では、基本情報技術者試験で使われる仮想マシン語CASLIIのススメ。 Z80ハンドアセンブルした小学生時代、CASLIIがJavaVMと似てると思った高専生時代が懐かしい。

私の一押しは、32bit CPU、Arm Cortex-M0のマシン語。IchigoJamで使っているLPC1114で使え、コンパクトで強力かつ、iPhoneなどスマホでも動きます。 (でも、本気で動かすなら64bit対応のArm64マシン語!)


連載、Armマシン語入門と合わせて使えるシミュレーター「avm」をつくってみました。フラグなどがいい加減で、まだ表示がないので、連載その2までの対応です。

サンプルのマシン語プログラムは、10から1までをループしながら足し算するプログラム。たかだか100円ちょっとのCPUですが、54サイクル、1.12μ秒(約100万分の1秒)で計算するパワーをフルに使い切る感こそ、マシン語の醍醐味!

JavaScriptでつくったシンプルなバーチャルマシン(VM)「avm」、どうぞいろいろ改造してお使いください!
IchigoJamで学ぶArmマシン語入門」と合わせてどうぞ!

iPhoneインラインアセンブラ入門、64bit Armマシン語はじめのいっぽ

2016/08/17
#Arm #swift 

IchigoJamもiPhoneも同じArmのCPU、IchigoJamでマシン語を覚えたらiPhoneでも使ってみましょう。今回の対象は、64bit化したArm64(Armv8)対応のiPhone5s以降です。ネットや書籍での資料には32bit時代のものも混在しているので注意が必要です。(iPhone Wikipedia)。

Swiftにはインラインアセンブラ機能はまだないようなので、Objective-CでGameをテンプレートに選び、次の行を viewDidLoad の [super viedDidLoad]; の後に追加します。

__asm__ volatile ("mov x0, x0");

※__asm__ はインラインアセンブラ、volatile で最適化を停止
エミュレーター向けだとコンパイルエラーになります。(IntelがArmライセンス取得とのことなので、MacBookへのArmv8組み込みにも期待!まずはApple-Aの生産から?詳しい解説記事


iPhoneでArm64マシン語、動きました!
(3Dの飛行機はサンプルのままで、今回のアセンブラでの動作とは無関係です)

mov x0, x0 は、レジスタX0の内容をレジスタX0に入れる(つまり、ほぼ何もしない)というマシン語を生成します。やっかいなことにこのコードはMacのiPhoneエミュレーターでは動きません。iPhoneエミュレーターはArmのCPUまでは動かしてくれないようです。実機向けにコンパイルすると動きます。(Arm64では64bitになったレジスタをRではなくXで呼ぶようになった様子)

Objective-Cでの変数との足し算をやってみます。

long num = 1; __asm__ volatile ( "mov x1, #1 \n\t" "add %[n], %[n], x1 \n\t" : [n] "+r" (num) : : "x1" ); NSLog(@"res: %ld\n", n);

コンソールに結果として 2 と表示されます。mov x1,#1 でレジスタX1に1を入れ、add命令で%[n]というコンパイラ任せなレジスタX?にX1の値を加えます。IchigoJamマシン語入門では X1=1 と表記していました。

最初のコロンの後 [n] "+r" (num) で、Objective-Cの変数numを%[n]というレジスタに割り当てて、読み書き"+"するよと指定しています。

三番目のコロンの後の "x1" で、インラインアセンブラ内で X1 レジスタを使用すると宣言して、前後のプログラムと干渉しないようにコンパイラに指定します。

これで基本はOKですね!
より詳しい解説は、こちら「Arm GCC Inline Assembler Cookbook」など参照ください

せっかくなので、アセンブラならでは機能を使った便利な関数を作ってみます。

- (unsigned long)rbit:(unsigned long)n { __asm__ volatile ( "rbit %[n], %[n] \n\t" : [n] "+r" (n) ); return n; }

rbitというのは、64のbit列を反転する命令です。普通に計算すると結構手間ですが、マシン語なら1クロック、0.1nsecで計算します!(参照、Arm64(Armv8) Assembly Programming (08) 分岐命令

iPhone(Armv8)とIchigoJam(Armv6-M)との比較です。

IchigoJamのCortex-M0のThumb-2命令とも互換性あるiPhone6sですが、浮動小数やSIMD命令など性能をフルに活かすならArm64マシン語プログラミングへのステップアップがオススメです!レジスタもたくさんあるので作るのも楽!

参考
- Arm64(Armv8) Assembly Programming (00)(とっても詳しいRAM64解説)
- 連載、IchigoJamではじめる、Armマシン語入門
- 連載、iPhoneゲームづくりからはじめる、Swift入門

掛け算もインクリメントも1クロック、BASICでカジュアルに使うインラインマシン語とツール紹介 - IchigoJamではじめるArmマシン語その7

2016/08/16
#IchigoJam #Arm 

じっくり取り組むマシン語も楽しいですが、手軽で便利なマシン語ならではの技を紹介します。

CPUには足し算、引き算、メモリアクセスなど基本的な機能の他に、CPUによってそれぞれ固有な機能があります。現代のパソコンやスマホに使われる高性能なCPUには、3Dグラフィックスや、音声、映像などの処理の高速化のために、4つの計算を同時に行うなどのSIMD命令が含まれます。ほとんどのスマホで使われているArmアーキテクチャー、Cortex-AにはNEONというSIMD機能が搭載されています。

電源が限られるモバイルにおいて、いかに無駄な電力消費を抑えつつ、サクサク軽快なアプリを提供するかが重要です。C、JavaScript、Swiftでは、CPU固有の機能を表現する方法がないので、マシン語を使って、コンピューターの性能をフルに引き出しましょう。誰かがつくった機能(ライブラリ)を使わせてもらうのもいいですが、自分でも作ってみたくもなるでしょう。(参考「iPhoneでのピクセル処理をNEON(ベクタ演算)を使って4倍高速化する」)

IchigoJamが使っている低電力CPU、LPC1114は、Arm Cortex-M0という、Cortex-Aと命令に互換性があるサブセット(一部)です。SIMD命令はありませんが、BASICやCでは扱えない特別な演算があるので、今回はそれらをカジュアルに使います。

Cortex-M0 マシン語表(抜粋)」に、特殊演算を追記しました。

※BIC:ビットクリア、ASR:符号付き右シフト、ROR:右ローテート
※REV:byteオーダー反転、REV16:byteオーダー反転(2byteずつ)、REVSH:符号付き16bitを反転32bit化
※ADC:キャリー付き足し算、SBC:キャリー付き引き算

IchigoJam BASICには当てはまる演算子がないために、関数のような書き方にしていますが、これらの計算はすべて、通常の計算と同様、1サイクルで処理できます。IchigoJamの場合、48MHzで動作させているので1サイクルは約21ナノ秒で計算は終了します(iPhone6sは最大1.84GHzなので約40倍高速な0.1nsec)。

BIC:指定したビット位置のみをクリアする。普通に書くと Rd = Rd & ~Rm と、2回の演算が必要。
ROR:指定した数だけ右にビットシフトして、はみ出た分は上位ビットにセットする。
REV16:16bitの上位8bitと下位8bitを入れ替える(上位32bitも同様に)

I2Cで外部センサーから取得したビッグエンディアン(=最初に上位8bitがある)なデータの読み取りに便利そうな rev16 を実際使ってみます。

[0]=`1011101001 000 000 'R0=rev16(R0) [1]=#4770 ?USR(#800,1) 256 ?HEX$(USR(#800,#3412)) 1234

#4770は呼び出し元に戻るRETURNのマシン語です。(Z80でいう#C9)
同じコードをIchigoJam BASICで書くと、下記のようになります。配列を使う場合長くなるので、繰り返し使うならちょっと有利です。

N=#3412 ?N<<8+N>>8

マシン語をいれておくメモリとして、PCG領域を借りて、下記のように書くこともできます。このように、別のプログラムでいろいろな便利な関数を用意しておき、メインのプログラムを呼び出すとメモリを有効に使えます。

10 POKE#700,#40,#BA,#70,#47:P=#700 20 ?HEX$(USR(P,#CDAB));HEX$(USR(P,#3412))

Cortex-M0 マシン語表(抜粋)」にサイクル数を追加しました。ほとんどの命令が1サイクルで終了することが分かります(LPC1114は掛け算も1クロック!)。実行時間が正確に計算できるのもマシン語のいいところです!

ハンドアセンブルでコツをつかんだら、アドレス計算も自動でやってくれるArmアセンブラ搭載、Mac/Windows/Linux対応IchigoJam用ツール「IJUtilities」が便利です。C言語からIchigoJam BASIC用のコードを生成する「rohiniku/IchigoJam_bin2poke」の逆アセンブル機能を使った解析も勉強に便利!

Armマシン語は、スマホでもそのまま活かせる究極の高速化テクニック。自分の書いたコードが実際どういうマシン語になるかだいたい想像できる程度には押さえておきましょう。

C言語やJavaScriptでお馴染みの「i++」という iに1足す演算子が、Swift3ではなくなってしまいます。MSXでZ80マシン語で1足す命令(INC)や1引く命令(DEC)を知っていたため、ごく自然に受け入れて今でもよく使っているだけにさみしいものがあります。Z80では1足す専用の命令、INCを使えば足し算命令ADDよりサイズが節約できました(機械語の手帳 ステート数表)。ただ、近年使われるよくArmは、1足すのも2足すのも255足すのも、速度もサイズも一緒。演算子削減の一因かもしれません。

ゲーム、スマホ、ロボット、クラウド、IoT、AIなど、奥深いプログラミングの世界も第一歩から!
福井新聞主催、PCN共催「福井県小中学生プログラミング・フェス2016」参加者募集中!

- 連載、IchigoJamではじめる、Armマシン語入門
1. はじめてのマシン語
2. ハンドアセンブルで超速計算!
3. マシン語メモリアクセスで画面超速表示!
4. マシン語でLEDを光らせよう!
5. 楽しさ広がるマルチバイトメモリアクセスとスタック
6. マシン語使いこなしTIPS
7. カジュアルに使うインラインマシン語
8. アセンブラを使って楽しよう
9. マシン語で高速SPI
10. マシン語を制するもの時間を制す
11. 画面をイチゴで埋め尽くす12の方法
12. レジスタ不足に上位レジスタとスタック操作

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