マイコン制御基礎の基礎

マイコン制御基礎の基礎(10)

白と黒とグレーゾーン 〜2進数と固定小数点〜

みわよしこ(執筆協力:山本栄一、小椋秀一、宇野雄騎)  2008/11/17

マイコン制御プログラムを自由自在に書けるようになろう! 前シリーズ「マイコン制御基礎以前」に続く本シリーズでは、アセンブリ言語の解説を中心に基礎力固めを目指す。(編集部)

- PR -

 私たちは普段、目の前のPCで高級言語やアプリケーションを使って実数を取り扱っている。しかし、2進数の整数しか理解できないはずのCPUに、なぜ、そんなことができるのだろうか?

 最終回となる今回はマイコンでの固定小数点計算を通じて、コンピュータの中の「小数点のある世界」をのぞいていく。そして、AVRアセンブラを通じて、“制御とセンシングへの道”の第一歩を確実に踏み出そう!

AVRマイコンの乗算命令

 今回の題材は、2進数での小数点の取り扱いと、固定小数点と符号付き小数(注1)の乗算だ。これを理解すれば、正負の実数が取り扱えるようになり、できることの幅が大きく広がるはずだ。

注1:時々「実数」と表記されるが、筆者には抵抗がある。実数は、小数で表現することのできない数も含んでいるからだ。

 AVRシリーズには、以下の6種類の乗算命令がある。

  • MUL 符号なし整数×符号なし整数
  • MULS 符号付き整数×符号付き整数
  • MULSU 符号付き整数×符号なし整数
  • FMUL  符号なし小数×符号なし小数
  • FMULS 符号付き小数×符号付き小数
  • FMULSU 符号付き小数×符号なし小数

 整数と小数で乗算命令を分けているのは、小数には「小数点」という存在があるからだ。小数点の位置を合わせておかなければ、正しい計算はできない。小数点の取り扱いには、固定小数点と浮動小数点があるが、ここで扱うのは固定小数点である。小数点は、7ビット目と6ビット目の間にあるものとする。このことを「(1.7形式)」と表記する。

 さらに、けた数を固定した世界で負の数を扱うには、「最上位ビットが符号である」という前提を設けなくてはならない。2進数の世界では、符号付き2進数表示を用いればよいのだが、「符号付き2進数であるかどうか」に関する情報がなかった場合、「11111110」は「254」でもあり、「−2」でもあり得る。

 さらに、符号付き2進数の場合、最上位ビットを符号として用いるため、数値として利用できるビット数が減る。つまり、扱える数値の範囲が狭くなるということだ。符号が不要であることが分かっていれば、その分だけ扱う数値の範囲を広くできる。このような事情から、マイコンに乗算器を搭載する場合、符号の有無によって乗算器(=乗算命令)を作り分けることが多い。

 今回は、被乗数と乗数の両方を「符号付き」とするFMULS命令を用いて、小数の乗算の取り扱いになじんでみよう。

サンプル−数値Aと数値Bの乗算を行うプログラム−

 今回のサンプルプログラムを以下に示す(リスト1)

; FMULS命令でAとB(固定小数点)の掛け算を行う
; A・Bとも正、Aは正でBは負、A・Bとも負、A=B=-1 の4パターン
;
; 結果はR1:R0に格納される
; 扱う数値のうち上位8ビットをPORTBに出力し、シミュレータのI/O Viewで確認できるようにする


.include "m16def.inc"

.def A         = R19
.def B         = R20
.def Temp      = R22

.equ ALL_PORT_OUTPUT = 0xFF

;-------------------------------------------------------
; 小数同士の乗算を行う
;-------------------------------------------------------

;PORT B の初期化(全ビットを出力にセット)

        ldi     Temp, ALL_PORT_OUTPUT
        out     DDRB, Temp

;正の数×正の数

        ldi A,0b01000000  ; 0.5
                out PORTB,A
        ldi B,0b00100000  ; 0.25
                out PORTB,B
        fmuls B,A
                out PORTB,R1

;負の数×正の数 

        ldi A,0b11000000  ; -0.5
                out PORTB,A
        ldi B,0b00100000  ; 0.25
                out PORTB,B
        fmuls B,A
                out PORTB,R1

;負の数×負の数

        ldi A,0b11000000  ; -0.5
                out PORTB,A
        ldi B,0b11100000  ; -0.25
                out PORTB,B
        fmuls B,A
                out PORTB,R1

;(−1)×(−1)=+1になる?

        ldi A,0b10000000  ; -1
                out PORTB,A
        ldi B,0b10000000  ; -1
                out PORTB,B
        fmuls B,A
                out PORTB,R1


; 最後に無限ループを書いておく
ENDLESS:
        rjmp ENDLESS


リスト1 FMULS命令で数値Aと数値Bの乗算を行うプログラム

 リスト1のコメントに記載したとおり、「FMULS命令で数値Aと数値Bの乗算を行う」だけのプログラムだ。

 数値Aと数値Bは、

  • A・Bとも正
  • Aは正でBは負
  • A・Bとも負
  • A = B = −1

の4パターンとする。

 取り扱う数値・計算結果は、「AVR Studio」のシミュレータの「I/O View」を用い、その場で目視で確認できるようにした。「AVR Studio」の使用方法については前シリーズ「マイコン制御基礎以前 第8回」を参照していただきたい。

 では、例によって「論よりRUN」で実行してみよう。プロジェクトを作成し、プログラムのビルドが成功したら、図1のように「I/O View」の「PORT B」を表示させ、その状態でプログラムのステップ実行が行えるようにしよう。プログラムのステップ実行を行う方法については、前シリーズ「マイコン制御基礎以前 第8回」を参照していただきたい。

図1 AVR Studioの画面 画像をクリックすると拡大表示します

>>プログラムをステップ実行し、2進数の小数を理解しよう

  • 連載バックナンバー
  • 全記事インデックス
  • 組み込み開発トップ
  • MONOistトップ

スキルアップ/キャリアアップ(JOB@IT)

スポンサーからのお知らせ

- PR -
@IT Sepcial

震災関連・復興支援情報

震災関連・復興支援情報
@IT MONOist/EE Times Japan/環境メディアの製造業技術者向け3メディアを中心に、震災関連/復興支援情報を集めました

次世代エンベデッドコーナー

次世代エンベデッド
“次世代”の組み込み機器を開発するエンジニアを支援するコーナー。新潮流・新技術をインタビューやコラム、解説記事で分かりやすく紹介!

Windows Embeddedコーナー

Windows Embedded
Windows Embedded専門コーナー。Windows Embedded StandardやWindows Embedded CEをはじめとする「Windows Embedded」ファミリの最新動向や技術情報をお届けします!!

Androidコーナー

Android
Android専門コーナー。組み込みデバイスへの適用からアプリケーション開発、イベントレポート、ニュースなどAndroidに関するさまざまな技術情報がここに集結!!

@IT MONOist 求人情報

- PR -