and.asm(リスト4)は、論理積の動作を確認するプログラムです。R0に格納された1010とR1に格納されている0101の論理積を演算するものです。このプログラムを実行するとR0の値は0となります。
ram[0] <=8'b1010_0101; // mvi r0,0101 ram[1] <=8'b00_001_000; // mov r1,r0 ram[2] <=8'b1010_1010; // mvi r0,1010 ram[3] <=8'b01010_001; // and r1 ram[4] <=8'b1001_0100; // jmp 4
xor.asm(リスト5)は排他的論理和の動作を確認するプログラムです。英語では“Exclusive Or”ですね。R0に格納された1010とR1に格納されている0101の排他的論理和を演算します。このプログラムを実行するとR0の値は1111となります。この演算をビット演算に適応すると各ビット単位でそれぞれが一致していれば0、そうでなければ1となります。半加算器はこの排他的論理和と論理積を組み合わせて行います。足し算にはなくてはならい演算回路です。また暗号の生成や解読などにもこのロジックはよく使われています。
ram[0] <=8'b1010_0101; // mvi r0,5 ram[1] <=8'b00_001_000; // mov r1,r0 ram[2] <=8'b1010_1010; // mvi r0,a ram[3] <=8'b01011_001; // or r1 ram[4] <=8'b1001_0100; // jmp 4
この命令もADD同様、キャリーフラグに影響を与える演算です。2通りのコードを用意しました。inc.asm(リスト6)がキャリーフラグに影響を与えないコード、inc2.asm(リスト7)がキャリーフラグに影響を与えるコードです。他の演算は結果がR0に格納される場合が多いのですがINCは全てのレジスタが演算対象です。
このinc.asmはINC命令の動作を確かめるコードです。指定されたレジスタに1を足してそのレジスタに格納します。R0の値5に1を足してR0の値は6になります。オーバーフローなどは起こしませんのでキャリーフラグの値には変化はありません。
ram[0] <=8'b1010_0101; // mvi r0,5 ram[1] <=8'b01100_000; // inc r0 ram[2] <=8'b1001_0010; // jmp 2
inc2.asmは、R0の値15に1を足すとR0の4ビットの枠を超えてしまいます。いわゆるオーバーフローが起こりますので、キャリーフラグの値は1となり、Tang NanoのオレンジのLEDも点灯します。
ram[0] <=8'b1010_0101; // mvi r0,15 ram[1] <=8'b01100_000; // inc r0 ram[2] <=8'b1001_0100; // jmp 2
not.asm(リスト8)は論理否定の動作を確認するプログラムです。各ビットで0を1、1なら0にする命令です。not.asmのサンプルコードだとR0の値が1010なので、各ビットを反転させて0101となります。この場合、演算の対象はR0ですが、8つのレジスタ全てに対してこの演算は可能です。
ram[0] <=8'b1010_0101; // mvi r0,5 ram[1] <=8'b01101_000; // not r0 ram[2] <=8'b1001_0010; // jmp 2
Copyright © ITmedia, Inc. All Rights Reserved.