いかにして問題を解くか

このサイトはGoogle Analyticsを利用しています。

AVR AVR-AS

参考資料

AVR Libc

ここをベースにしてインストールする。

binutils

アセンブラとかが入っている。 avr-gcc もこれを使っている。

インストール先のディレクトリを適当に設定する。

$ mkdir /home/so/work/avr/local

Download

GNU Binutils

FTP サイトから最新の tar.gz をダウンロードして、展開する。

Install

展開したディレクトリに入って

$ ./configure --prefix=/home/so/work/avr/local --target=avr --disable-nls
$ make -j 4
$ make install

で出来上がるので、パスを通して使いやすくする。 make の -j 4 オプションは並列コンパイルオプションなので、環境に合わせて変更してください。

export PATH=$PATH:~/work/avr/local/bin

上記は bash の例で、~/.bashrc に書いておけば毎回設定する必要はありません。

Usage

avr-as usage tutorial

上記サイトを参考にして、動作確認をする。

.equ PORTB,0x18
.equ DDRB, 0x17

.org 0x00
reset:
rjmp main;
rjmp defaultInt;
rjmp defaultInt;
rjmp defaultInt;
rjmp defaultInt;
rjmp defaultInt;
rjmp defaultInt;
rjmp defaultInt;
rjmp defaultInt;
rjmp defaultInt;
rjmp defaultInt;
rjmp defaultInt;
rjmp defaultInt;
rjmp defaultInt;
rjmp defaultInt;

defaultInt:
reti;

main:
sbi DDRB, 0;
cbi DDRB, 0;

end:
rjmp end;
avr-as -mmcu=attiny13a -o sample.o sample.s 
avr-ld -o sample.elf sample.o 
avr-objcopy --output-target=ihex sample.elf sample.ihex

.o, .elf はバイナリファイルで、バイナリエディタで確認する必要がある。 最後のihexはテキストデータで、"intel hex format"という形式であり、テキストエディタで普通に読める。

:100000000FC00DC00CC00BC00AC009C008C007C09B
:1000100006C005C004C003C002C001C000C01895DE
:06002000B89AB898FFCF6A
:00000001FF

intel hex format

一文字が16進数を表し、0x0-0xF(0-15) までが表現できる。 最初の ":" は行頭を示すフラグです。

Start code Byte count Address Recode type Data Check sum
: 10 0000 00 0FC00DC00CC00BC00AC009C008C007C0 9B
: 10 0010 00 06C005C004C003C002C001C000C01895 DE
: 06 0020 00 B89AB898FFCF 6A
: 00 0000 01 FF

上記の表のように分解でき、Recode type は

Recode type Description
00 Data
01 End of file

である。

hex ファイルの解析

AVR ATtiny13 の FlashROM は 1 word が 16bit なので、 2 Byte ずつアドレスが若い方から埋まっていく。

AVR が リトルエンディアンであるため DATA もリトルエンディアンになっており、 上位 1 Byte, 下位 1 Byte を入れ替えて解読する必要がある。

Address DATA OPECODE OPERAND0 OPERAND1 MNEMONIC
0x00 0x0FC0 0b1100 0b001111 RJMP
0x02 0x0DC0 0b1100 0b001110 RJMP
0x04 0x0CC0 0b1100 0b001101 RJMP
0x06 0x0BC0 0b1100 0b001100 RJMP
0x08 0x0AC0 0b1100 0b001011 RJMP
0x0A 0x09C0 0b1100 0b001010 RJMP
0x0C 0x08C0 0b1100 0b001001 RJMP
0x0E 0x07C0 0b1100 0b001000 RJMP
0x10 0x06C0 0b1100 0b000111 RJMP
0x12 0x05C0 0b1100 0b000110 RJMP
0x14 0x04C0 0b1100 0b000101 RJMP
0x16 0x03C0 0b1100 0b000100 RJMP
0x18 0x02C0 0b1100 0b000011 RJMP
0x1A 0x01C0 0b1100 0b000010 RJMP
0x1C 0x00C0 0b1100 0b000001 RJMP
0x1E 0x1895 0b1001010100011000 0b0000 RETI
0x20 0xB89A 0b10011010 0b10111 0b000 SBI
0x22 0xB898 0b10011000 0b10111 0b000 CBI
0x24 0xFFCF 0b1100 0b111111111111 RJMP

RJMP のオペランドは2の補数なので、0b111111111111 は 10進数で表現するなら -1 です。