16進数
コンピュータのソフトウェアでは数値を表すのに16進数を使用することが多いです。
16進数を理解するために日常私たちが使っている10進数から始めます。
10進数
私たちの日常生活では"0"から"9"までの10個の数を使っています。
9の次は10と桁上げが行われます。何の不思議もなく使っていますが、これは単に人間が決めた数の表し方です。
人間の手の指が10本と言うことから決められたという説もあります。
2進数
コンピュータを含めたデジタルの世界では状態を表すのに"0"および"1"の二つの値だけが使われます。これらは "Lowレベル" および "Highレベル" で表されることもあります。
0 → 1 → 10 のように 1 の次が 10 と桁上げが行われます。
16進数
コンピュータで扱っている状態は2進数なのですが、10進になれている人間には非常に見づらい表示になります。
163(10進) → 10100011(2進)
そこで、もう少し人間に分かりやすい表現として16進が使われています。16進は1桁に16個の数が使われます。数字は0から9までしかありませんので、残りの6個はアルファベットで表現されます。
10 → A 、11 → B 、12 → C 、13 → D 、14 → E 、15 → F
数字は0から始まっているので、数字の10は11番目を表し、15は16番目を表します。
16種類の状態は2進数では4ビットで表されます。逆に4ビットで表せるのが16なので16進数が使われています。3ビットの場合に8種類の状態を表す8進数と言うのもあります。16進数の場合、8ビット(1バイト)は2桁で表現されます。
また、16進数を10進数と区別するために"h"を付けて表現します。hはhexadecimal(16)の頭文字です。
00hとかH'00'とか0x00とかで表しますが、表現方法は必ずしも統一はされていません。
各数字の対応
2進数、10進数、16進数を対応させると以下のようになります。
10進数 | 2進数 | 16進数 |
| 10進数 | 2進数 | 16進数 |
0 | 0 | 0h | 100 | 1100100 | 64h |
1 | 1 | 1h | 127 | 1111111 | 7Fh |
2 | 10 | 2h | 128 | 10000000 | 80h |
3 | 11 | 3h | 200 | 11001000 | C8h |
4 | 100 | 4h | 255 | 11111111 | FFh |
5 | 101 | 5h | 256 | 100000000 | 100h |
6 | 110 | 6h | 300 | 100101100 | 12Ch |
7 | 111 | 7h | 400 | 110010000 | 190h |
8 | 1000 | 8h | 500 | 111110100 | 1F4h |
9 | 1001 | 9h | 511 | 111111111 | 1FFh |
10 | 1010 | Ah | 512 | 1000000000 | 200h |
11 | 1011 | Bh | 600 | 1001011000 | 258h |
12 | 1100 | Ch | 700 | 1010111100 | 2BCh |
13 | 1101 | Dh | 800 | 1100100000 | 320h |
14 | 1110 | Eh | 900 | 1110000100 | 384h |
15 | 1111 | Fh | 1000 | 1111101000 | 3E8h |
16 | 10000 | 10h | 1023 | 1111111111 | 3FFh |
17 | 10001 | 11h | 1024 | 10000000000 | 400h |
18 | 10010 | 12h | 2000 | 11111010000 | 7D0h |
19 | 10011 | 13h | 2047 | 11111111111 | 7FFh |
20 | 10100 | 14h | 2048 | 100000000000 | 800h |
2進数、10進数、16進数の変換はWindowsに付属している電卓アプリケーションの関数電卓を使えば簡単に変換することができます。
手計算で変換する場合には以下の方法を使えば割と楽に変換できます。
2進数→16進数: |
4ビットづつ区切れば簡単に変換できます。
1100だったらChとか1010だっらAhとかAhからFhまでの2進数パターンを覚えてしまえばもっと楽です。
例 111000100100010000100 → 1C4884h |
16進数→2進数: |
16進数を1桁づつ2進数にして並べれば変換できます。
例 5F37Bh → 1011111001101111011 |
2進数→10進数: |
これはちょっと面倒です。
下図のように1ビットずつに10進での値を書き、1が立っているビットの10進数を合計します。
例
512 + 256 + 128 + 8 + 4 + 1 = 909 |
10進数→2進数: |
これもちょっと大変。
10進数から引き得る最大の2のべき数(1,2,4,8,16,32,64,128,256,512,1024,・・・)を引きます。
引けたべき数に相当するビットに1を立てます。
余りからさらに引き得る最大の2のべき数を引きます。
以下同様な引き算を繰り返して、余りがなくなるまで繰り返します。
以上の結果で1と0の並びが2進数です。
例 "582"の場合
582 - 512 = 70
70 - 64 = 6
6 - 4 = 2
2 - 2 = 0
|
10進数→16進数: |
10進数を2進数に変換し、それを16進数に変換します。
上の10進数→2進数の例の場合、 582 = 1001000110 = 246h です。
直接変換する場合には4ビット毎の値で割る方法もあります。
582 ÷ 256 = 2 余り 70
70 ÷ 16 = 4 余り 6
答えは246hになります。 |
16進数→10進数: |
16進数を2進数に変換し、それを10進数に変換します。
上の2進数→10進数の例の場合、38Dh = 1110001101 = 909 です。
直接変換する場合には4ビット毎の値を掛ける方法もあります。
3 x 256 = 768
8 x 16 = 128
768 + 128 + 13(Dh) = 909 になります。 |
やはり関数電卓で計算した方が楽ですね。
2の補数
2の補数とはマイナスの数値を表すものです。
例えば10進数で−1は8ビットの2進数で表すと 11111111 になります。
検算すると以下のようになり、-1 を表していることが分かります。
オーバーフローが発生しますが、数値はゼロになります。
2進数の足し算の方法は10進数と同じように下位の桁から足して、桁上げがあった場合にはそれを含めて次の桁を計算するという方法で行います。
マイナスの値を使うのには条件があります。
8ビットで表せる数値は0〜255の256種類ですが、マイナスの数値のを使うとした場合には−127〜+127の255種類になります。一つ少ないのは 10000000 が使われないからです。このビットの並びは -0 を表しますが、計算上では使えません。
最上位のビット7はプラスかマイナスを表す符号ビットとしての意味を持ちます。
数値がプラスだけなのかプラス/マイナスを表すのかは処理するときに意識する必要があります。
例えば -127 を2進数で表すと 10000001 です。プラスのみの数値とすると 129 を表しているように見えてしまいます。
2の補数への変換の方法は以下のように行います。
例として 56 を -56 に変換してみます。
(1) プラスの数値から1を引く | 56 - 1 = 55 |
(2) これを2進数に変換する | 55 → 00110111 |
(3) 0と1を逆にする | 00110111 → 11001000 |
11001000 が -56 を表す2進数です。
検算してみます。
答えはゼロになりました。
命令の構造
PIC16シリーズの命令の構造は以下の3種類です。命令はプログラムメモリーに書かれ、1つの命令は14ビットで構成されています。この14ビットはワードと呼ばれています。
| バイト処理命令 |
| この構造の命令はバイト単位の処理を行う命令です。 |
| | |
| | 命令コード : | 命令を識別するためのコードが書かれます。 |
|
d (Destination select) : |
命令の実行結果を格納する場所を指定します。
d=0の時は ワーキングレジスタ(Wreg) を指定します。
d=1の時は f で指定されている file register を指定します。
アッセンブラ言語で書いた場合、この d はWかFで書きます。 |
| (例) | ADDWF | COUNT,W | (Wと書くとd=0) |
| ADDWF | COUNT,F | (Fと書くとd=1) |
|
f (Register file) : |
命令の対象となる変数レジスタのアドレスを指定します。
f は7ビットなので 0(00h) から 127(7Fh) までのアドレスを指定することができます。
PIC16F84Aの場合、レジスタ・メモリはSFRを含めて80バイトですから、7ビットあれば指定できます。
アッセンブラ言語で書いた場合、変数レジスタにラベルを付け、そのラベルを指定します。 |
| (例) | ADDWF | COUNT,F | (COUNTが変数レジスタのラベルです) |
|
|
| ビット処理命令 |
| この構造の命令はビット単位の処理を行う命令です。 |
| |
命令コード : | 命令を識別するためのコードが書かれます。 |
|
b (Bit address) : |
レジスタ・ファイルのビット位置を指定します。
レジスタ・ファイルは8ビットですので、b として3ビットあれば任意のビットを指定できます。 |
|
f (Register file) : |
命令の対象となる変数レジスタのアドレスを指定します。
f は7ビットなので 0(00h) から 127(7Fh) までのアドレスを指定することができます。
PIC16F84Aの場合、レジスタ・メモリはSFRを含めて80バイトですから、7ビットあれば指定できます。
アッセンブラ言語で書いた場合、変数レジスタにラベルを付け、そのラベルを指定します。 |
|
|
|
|
|
|
|
|
|
| リテラル処理命令 ( リテラル(Literal)とは"文字通りの"とか"そのまま"という意味 ) |
|
|
|
この構造の命令は命令の中に書かれた定数(k)を使った処理を行います。
命令構造は2通りあり、GOTOおよびCALL命令は定数(k)が11ビットになっています。 |
|
|
GOTO および CALL命令の場合
|
命令コード : | 命令を識別するためのコードが書かれます。 |
|
k (Literal field) : |
演算の対象とする定数です。数値またはラベルで指定します。
GOTO および CALL命令以外では8ビットですので、0(00h)〜255(FFh)の範囲です。
GOTO または CALL命令では11ビットですので、0(00h)〜2047(7FFh)の範囲です。 |
|
|
|
|
|
|
|
|
|