第 4 回 アセンブリ言語

本日の内容


このドキュメントは http://edu.net.c.dendai.ac.jp/ 上で公開されています。

4-1. 準備

機械語とはコンピュータ(CPU)を動作させるための数値列の事です。 ATtiny2313 では 16bit または 32 bit で 1 つの命令を表します。 一方アセンブリ言語とはこれらの数値をその機能などが直観でわ かるように英単語や記号等を当てはめた物です。 アセンブリ言語で記述されたプログラムを機械語に直す事をアセンブル と言います。また、アセンブルを行うコンピュータプログラムを アセンブラと言います。 但し、アセンブリ言語をアセンブラと呼ぶ事もあります。

アセンブラの最新のマニュアルは PDF になってなく、 HTML バージョン だけあります。 ver. 1 のアセンブラ用のマニュアルは PDF になってます。 ver.1 に無くて、 ver. 2 にあるのは、条件アセンブリやプリプロセッサの機 能です。

リテラル(定数)

機械語やアセンブラでは頻繁に十六進数など、十進数以外の表記を使います。 これらのルールはアセンブラのマニュアルにあります。

十進数
0で始まらない 0から9までの数の集まり。 または単体の0。 また、マイナス記号が使えるので、負の数も使用できます。
十六進数
$または 0x で始めると十六進数を表します。 $F, $0f, 0xF, 0x0f など
二進数
0b で始めると二進数を表します。 0b00010101 など。
八進数
0で始めて 0 から 7 の列で八進数を表します。

アセンブリ言語は一つの機械語を機能と引数に分けて表現します。 機能の部分をmnemonic(ニモニック)と呼び、引数をオペラン ドと言います。 例えば、0000 1100 0000 0000は R0 レジスタと R0 レジスタを 足して、 R0 に収める機械語です。 また、0000 1100 0000 0001 は R0 レジスタと R1 レジスタを 足して、 R0 に収める機械語です。 一方、0000 1100 0001 0000 は R1 レジスタと R0 レジスタを 足して、 R1 に収める機械語です。 総称すると、0000 11rd dddd rrrrは Rd レジスタと Rr レジスタを 足して、 Rd に収める機械語です。 したがって、これらに対して機能を表すニモニックを add とし、Rd と Rr の 部分をオペランドとします。 つまり、Rd レジスタと Rr レジスタを足して Rd に収めることを、アセンブリ 言語で表現すると add Rd,Rr となります。 オペランドとして、メモリの番地の他、ビット位置や、定数(リテラル)、演算 結果の収納先などを指定することができます。

4-2. アセンブリ言語

基本書式

アセンブリ言語はテキストファイルに記述します。 アセンブラのユーザーズマニュアル AVR Assembler Assembler source に示されているように記述します。 「ラベル: ニモニック オペランド」 を空白で区切って記述します。 ラベルの前に空白があってはいけません。 また、セミコロン(;)の後ろはコメントとしてアセンブル時に無視されます。 ニモニックの位置には他にディレクティヴ、マクロなどを置くことができます。


ラベル  ニモニック オペランド コメント
.org	0x0013
reset:
	ldi	r16,low(RAMEND)
	out	SPL,r16

演算

アセンブリ言語中で定数の演算式を書くことが出来ます。 アセンブラのユーザーズガイドの AVR Assembler Expressions にあるように C 言語で許されて いるような演算子がそのまま使えます。 但し、レジスタの内容は演算の対象ではありません。

ディレクティヴ

アセンブラとはニモニックとオペランドから機械語を生成するものですが、 利便性を向上するためのアセンブラの機能があります。 ディレクティヴとはアセンブラに対する指示をする命令です。 ディレクティヴはピリオド(.)で始めます。

良く使うディレクティヴを紹介します。

device
アセンブラの動作を変化させるディレクティヴです。 .device attiny2313 とすると使用プロセッサを ATtiny 2313 にするこ とができます。 ただ、次の include で使う ATtiny2313 用のファイル内でも指定されています。
include
C 言語同様にファイルを読み込みます。Atmel Studio には各マイコンご とに定義ファイルが用意されています。 .include <tn2313def.inc> として定義ファイルを読み込むと、各 I/O Register のビットを名前で参照し たりできるようになります。 なお、 tn2313def.inc は C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR Assembler\Native\2.1.39.1005\avrassembler\include にあります(バージョ ンにより多少位置は異なります)。 インクルードファイルの内容はプログラムを組む時重要になりますので、印刷してお いて下さい。
cseg, dseg, eseg
それぞれ、 Code, Data, EEPROM の内容を定義するという意味です。
equ
任意の値を持つラベルを定義します。再定義できません。 計算値も定義できます。
def
レジスタにラベルを定義します。再定義できません。 これを使用すると、レジスタの利用を論理的に表示できるので、 必ず使うことを推奨します。
org
実際のプログラムやデータを置く始点となる番地を指定します。
db, dw, dd, dq
データをじかに書きます。 db は Byte, dw は Word(16bit)の定義に使います。カンマ(,)で区切るといく つも定義できます。 なお、プログラム領域(cseg で定義される領域)は 16bit です。 lpm 命令で 8bit ずつ取り出す場合、下位 8bit がアドレスの偶数番地、上位 8bit が奇数番地に対応します。さらに、奇数個のデータを入れると、上位 8bit が $00 で埋められます。
byte
dseg で SRAM の領域にラベル付きの領域を定義する際に使用します。
exit
アセンブリのリストの最後を示します。
macro, endmacro

マクロを定義します。 macro のオペランドにマクロ名を指定します。 マクロ定義の中で引数として @0 から @9 の 10 個の仮引数が使えます。 なお、AVR のアセンブラのマクロ中のラベルはローカルにしか使用できません ので、マクロ中に定義したラベルに外部からアクセスすることはできません。 なお、グローバルなラベルを使用するには #define 疑似命令を使用する手が ありますが、こちらこちらで基本的に一行で記述しなければならず、複数行を 書くには(\)を使用した継続行を使用する必要があります。

4-3. 関数

EQU などで使用できる関数を下記に示します。 なお、これらは一部なので、詳しくは アセンブラマニュアル Expressions を参照してください。

LOW(式)
式の値の下位8bitを取り出します
HIGH(式)
式の値の上位8bitを取り出します
EXP2(式)
式の値の2のべき乗を返します。 (1<<式)と同等です
LOG2(式)
式の値の 2 を底とした対数の整数部分を返します
INT(式)
式の値を切り捨てます
FRAC(式)
式の値の小数部分を取り出します
ABS(式)
式の値の絶対値を返します

4-4. アセンブル

さて、この節では実際にプログラムを作成する手順を説明します。

  1. Atmel Studio を起動します。
  2. 「File→New→Project」を選びます。
  3. Installed Template で Assembler を選び、name にプロジェクト名を入 れます
  4. Device Family で tinyAVR,8bit を選び、 ATtiny2313 を選びます
  5. プロジェクト名.asm という編集画面が開きますので、プログラムを入力します。
  6. 「File→Save プロジェクト名.asm」でプログラムを保存します。
  7. 「Build→Build Solution」でアセンブルします。
  8. アセンブルエラーが出た場合、エラーをダブルクリックするとエラーの出 た行へカーソルが移動します。

4-5. シミュレータを使ったデバッグ

アセンブルしたプログラムはシミュレータで動作を観察できます。 Project → プロジェクト名 Property を選ぶと 設定画面が出ます。 Tool の設定画面で、 Simulator を選ぶと ソフトウェアシミュレータ を使えるようになります。 シミュレータはプログラムを一命令ずつ動かしたり、指定した所まで動かして 止めたり出来ます。

シミュレータはテープレコーダのボタンのようなボタンで操作をします。 なお、 右側の画面でマイコンの状態を見ることができます。

プログラムリストの行をダブルクリックすると左側に赤い丸が付きます。 これを ブレークポイントと言います。 矢印一つの Run ボタンを押すと、ブレークポイントで停止します。 これにより、プログラムの途中のレジスタの値などをチェックできます。

その他、一命令だけ実行する Step Into, Call 命令に関しては戻って来るま で一括で実行する Step over, サブルーチン中から抜け出すまで実行する Step out があります。

なお、実行中にI/Oのボタンを押すと、その値に変化させることができます。

4-6. 実行

アセンブリ言語のプログラムは Build すると HEX ファイルが作られます。 これをマイコンに書き込むには次のようにします。

  1. 回路と In System Programmer とパソコンを接続します。 In System Programmer の USB ポート付近の LED が緑に点灯して、回路側の  LED が赤に点灯すれば正常です。
  2. 回路の電源を入れます。 回路側の LED が緑に変われば正常です。
  3. Atmel Studio において Tools→Device Programming を選択します。
  4. Tool に AVRISP mkII を選び、 Device に ATtiny2313 を選び Apply を押し ます
  5. Memories のタブに行き、ファイルとして、作成したプロジェクトの Debug の 中にある「プロジェクト名.hex」ファイルを選択します
  6. Program を押すとマイコンに書き込まれ、動作を開始します。

4-7. 演習問題

演習4-1

前回のサンプルプログラム sw.asm の各ディレクティヴがどのような意味か、全て調べなさい。

演習4-2

前回のサンプルプログラム sw.asm を機能毎に区分し、各機能を説明しなさい。

演習4-3

前回のサンプルプログラム flash.asm の各ディレクティヴがどのような意味か、全て調べなさい。

演習4-4

前回のサンプルプログラム flash.asm を機能毎に区分し、各機能を説明しなさい。


坂本直志 <sakamoto@c.dendai.ac.jp>
東京電機大学工学部情報通信工学科