■ PIC16C6x/C7x/C84 用クロス・アセンブラ (1996年8月版) ■ 幾島康夫 ■ PIC16C6x/PIC16C7xでの注意点 A) コンフィグレーション・メモリにID領域が無いものがあります。 このような場合には、ID領域を使わないようにして下さい。 B) コンフィルレーション・ヒューズの仕様がPIC16C84と違うものがあります ので、確認してから設定して下さい。 C) 現状ではPIC16C84以外にはデータ用EEPROMは内蔵されていませんので、 PIC16C84以外では#DAT命令は使わないで下さい。 D) ソース・ファイルの制限が出来ましたので、ROM サイズの大きな PIC では、ファイルが大きくならないように注意して下さい ■ 使用方法 1. バッチ・ファイルによる起動 1) 下記の環境変数をセットして下さい。 CASM : CPICASMP,1,2,3,4 の実行ファイルが置かれたパス 例) SET CASM=A:\PICASM\ ;最後は必ず '\' で終わること TMP : 作業ファイル及びオブジェクト・ファイルが置かれるパス 例) SET TMP=G:\ ;最後は必ず '\' で終わること 2) CPICASM.BAT にパスを通す 3) CPICASM.BAT SOURCE.ASM でアセンブル実行 4) 作業ディレクトリに下記のファイルが作成される OUT.ADD : ソース・ファイルにインクルード・ファイルが結合されたもの OUT.PS1 : 命令、ラベル名、定義名などが抽出されたファイル OUT.LST : リスト・ファイル OUT.TXT : 独自形式のオブジェクト・ファイル OUT.OBJ : インテル HEX フォーマットのオブジェクト・ファイル 5) 途中レジスタ・ファイルの自動割付状況及び ROM の残りサイズを表示します 6) エラーの検出 エラーが検出されると、バッチ・ファイルは終了する。 エラー・メッセージは画面に表示される。 エラー・メッセージにはエラーが発生したファイルの名前と、当該ファイル の行番号が表示される(一部表示されないものもあります)。 7) 高速化 RAMディスク等を作業ドライブとして使う 2. コンパイラ・ドライバによる起動 1) CPICASM.EXE にパスを通す 2) CPICASM.EXE SOURCE.ASM でアセンブル実行 4) SOURCE.ASM が置かれたディレクトリに下記のファイルが作成される SOURCE.ASM : ソース・ファイルにインクルード・ファイルが結合されたもの SOURCE.PS1 : 命令、ラベル名、定義名などが抽出されたファイル SOURCE.LST : リスト・ファイル SOURCE.TXT : 独自形式のオブジェクト・ファイル SOURCE.OBJ : インテル HEX フォーマットのオブジェクト・ファイル エラーが無い場合、SOURCD.OBJ を残して他の作業ファイルは消去される 5) 途中レジスタ・ファイルの自動割付状況及び ROM の残りサイズを表示します 6) エラーの検出 エラーが検出されると、プログラムは終了する。 エラー・メッセージは画面に表示される。 エラー・メッセージにはエラーが発生したファイルの名前と、当該ファイル の行番号が表示される(一部表示されないものもあります)。 7) 高速化 RAMディスク等にソース・ファイルを置いて実行する。 ■ 動作環境 動作確認は PC-9801RA(DOS 5.0), PC-9821Ld(DOS 6.2) のみですが、DOS環境で あればAT互換機でも動くと思います。 動作させるためには、ある程度のメモリが必要です。 WINDOWS の DOS窓 で使用する場合は注意して下さい。 ■ 文法 1. 1行の長さ 255文字以内です。 2. コメント 行頭が '/*' '%' で始まる行は、コメント行として扱います。 例) /* コメント行です % これもコメント行 また、命令の後にも、';' の後にコメントを入れることが可能です。 例) MOVF TMRO, WREG ;コメント 3. 命令 1) 使用可能なニモニック(Mnemonic) ADDWF f,d ANDWF f,d CLRF f CLRW COMF f,d DECF f,d DECFSZ f,d INCF f,d INCFSZ f,d IORWF f,d MOVF f,d MOVWF f NOP RLF f,d RRF f,d SUBWF f,d SWAPF f,d XORWF f,d BCF f,b BSF f,b BTFSC f,b BTFSS f,b ADDLW k ANDLW k CALL k CLRWDT GOTO k IORLW k MOVLW k OPTION RETFIE RETLW k RETURN SLEEP SUBLW k TRIS f XORLW k ただし、 f : レジスタ・ファイル・アドレス d : 宛先指定子 b : レジスタ・ファイル・ビット指定 k : 定数 2) レジスタ・ファイル・アドレス f の記述方法 MOVF TMR0, d ;f を定義名で指定 MOVF #0Fh, d ;f を 16進数(00h - 7Fh) で直接指定 'h' は 16進数であることを明示するためのものですが、 省略可能です MOVF #.16, d ;f を 10進数(.0 - .127) で直接指定 '.' は 10進数であることを明示するためのもので省略す ることは出来ません MOVF #00001111b, d ;f を 2進数(00000000b - 01111111b) で直接指定 'b' は 2進数であることを明示するためのものですが、 省略可能です MOVF #'A', d ;f を ASCIIキャラクタ(20h - 7Eh) で直接指定 ' で囲む必要がある ' 自身も ''' で指定可能です 3) レジスタ・ファイル・ビット指定 b の記述方法 BTFSC f, DC ;b を定義名で指定 BTFSC f, #1 ;b を数値(0 - 7)で直接指定 BTFSC STATUS.DC ;f と b をビット定義名で同時に指定 4) 宛先指定子 d の記述方法 MOVF f, WREG ;d を定義名で指定 MOVF f, #1 ;d を 1 又は 0 で直接指定 MOVF f ;d を省略すると d=1 と等価になり 結果はレジスタ・ファイルに入ります 5) 定数 k の記述方法 MOVLW TEST ;k を定義名で指定 MOVLW #TEST ;k を定義名で指定 MOVLW #0Fh ;k を 16進数(00h - FFh) で直接指定 'h' は 16進数であることを明示するためのものですが、 省略可能です MOVLW #.16 ;k を 10進数(.0 - .255) で直接指定 '.' は 10進数であることを明示するためのもので省略す ることは出来ません MOVLW #00001111b ;k を 2進数(00000000b - 11111111b) で直接指定 'b' は 2進数であることを明示するためのものですが、 省略可能です MOVLW #'A', d ;k を ASCIIキャラクタ(20h - 7Eh) で直接指定 ' で囲む必要がある ' 自身も ''' で指定可能です CALL MAIN ;k がアドレスの場合(CALL k and GOTO k)は、ラベル名で 指定する 4. 疑似命令 1) 使用可能な疑似命令 #ORG k ;ROM アドレスを k で指定します #LBL name ;ラベル名 name でラベルを定義 #LBL [0123456789] ;ラベル名 0 〜 9 は ローカル・ラベルとして定義されま ;す。ローカル・ラベルは、ラベル名の重複チェックは行い ;ません。 ;ローカル・ラベルに分岐する場合は、 ; #LBL 0 ;(B) ; : ; GOTO 0f ;ラベル名 0 を前方検索し(A)に分岐 ; : ; GOTO 0b ;ラベル名 0 を後方検索し(B)に分岐 ; : ; #LBL 0 ;(A) ;のように、ラベル名の後に f(F) 又は b(B) を付けて ;検索方向を必ず指定します #CNF addres data ;コンフィグレーション領域(2000h - 2007h番地)のデータ を設定します #DAT addres data ;データ用EEPROM領域(00h - 3Fh番地)のデータを設定しま す #DEF name k ;定義名 name で定数 k を定義 #DEF name f ;定義名 name でレジスタ・ファイルのアドレス f を定義 #DEF name b ;定義名 name でレジスタ・ファイルのビット b を定義 #DEF name d ;定義名 name で宛先指定子 d を定義 #DEF name *+ ;定義名 name にレジスタ・ファイルを自動割付 ;name にアドレスを割り付けた後、割付用アドレス ;カウンタをインクリメントします。よって、 ; #DEF TEST1 *+ ;TEST1 は アドレス n に割付 ; #DEF TEST2 *+ ;TEST2 は アドレス n+1 に割付 ;となります。 #DEF name * ;定義名 name にレジスタ・ファイルを自動割付 ;name にアドレスを割り付けますが、割付用アドレス ;カウンタはインクリメントしません。よって、 ; #DEF TEST1 * ;TEST1 は アドレス n に割付 ; #DEF TEST2 *+ ;TEST2 は アドレス n に割付 ;となり、1つのアドレスに複数の名前を定義することが ;可能となります。 #DEF name2 name1 ;name2 に name1 で定義された数値等を定義します ;ただし、name1 は この命令が置かれる位置より前で定義 ;されている必要があります。 #BITDEF name f b ;ビット定義名 name にレジスタ・ファイル f と ビット b ;を同時に定義 #BITDEF name *+ b ;ビット定義名 name にレジスタ・ファイル(自動割付)と ;ビット bを同時に定義 ;name にアドレスを割り付けた後、割付用アドレス ;カウンタをインクリメントします。よって、 ; #BITDEF TEST1 *+ 0 ;TEST1 は アドレス n の bit 0 ; ;に割付 ; #BITDEF TEST2 *+ 1 ;TEST2 は アドレス n+1 の ; ;bit 1 に割付 ;となります。 #BITDEF name * b ;ビット定義名 name にレジスタ・ファイル(自動割付)と ;ビット b を同時に定義 ;name にアドレスを割り付けますが、割付用アドレス ;カウンタはインクリメントしません。よって、 ; #BITDEF TEST1 * 0 ;TEST1 は アドレス n の bit 0 ; ;に割付 ; #BITDEF TEST2 * 1 ;TEST2 は アドレス n の bit 1 ; ;に割付 ; : ; #BITDEF TEST7 * 6 ;TEST7 は アドレス n の bit 6 ; ;に割付 ; #BITDEF TEST8 *+ 7 ;TEST8 は アドレス n の bit 7 ; #DEF TMP *+ ;TMP は アドレス n+1 に割付 ;のようにすると、TEST1〜TEST8を同一アドレスに定義 ;する事が可能となります #BITDEF name2 name1 ;name2 に name1 で定義された、数値等を定義します ;ただし、name1 は この命令が置かれる位置より前で定義 ;されている必要があります。 #BITDEF name2 name1 b ;name2 に #DEFで定義された name1 レジスタの ビット ;b を定義します。 ;ただし、name1 は この命令が置かれる位置より前で定義 ;されている必要があります。 #MAXROMSIZE k ;ROM のサイズを定義 (定義しない場合 ROMサイズは 1024語 です) #INCLUDE filename ;filename で指定したファイルをソース中に埋め込む ;filename はフル・パスでも相対パスでも可 #EXTERN name ;#DEF,#BITDEF で定義されている name の内容を参照 ;Include ファイルに命令コードを記述する場合に、 ;ファイル内で使用する変数を定義しておくと便利です #AUTO_MIN_ADDRESS f ;アドレス自動割付の、割付開始アドレスの定義 ;(定義しない場合は 割付開始アドレスは 0Ch です) ;f は 16進数(00h - 7Fh)で指定 ;#AUTO_MIN_ADDRESS <= #AUTO_MAX_ADDRESS であること #AUTO_MAX_ADDRESS f ;アドレス自動割付の、割付上限アドレスの定義 ;(定義しない場合は 割付上限アドレスは 2Fh です) ;f は 16進数(00h - 7Fh)で指定 ;#AUTO_MIN_ADDRESS <= #AUTO_MAX_ADDRESS であること ;#AUTO_MAX_ADDRESS で定義したアドレスを超えて割り付け ;ようとするとエラーとなります。 2) レジスタ・ファイル・アドレス f の記述方法 #DEF TEST 0Fh ;f を 16進数(00h - 7Fh) で直接指定 'h' は 16進数であることを明示するためのものですが、 省略可能です #DEF TEST .16 ;f を 10進数(.0 - .127) で直接指定 '.' は 10進数であることを明示するためのもので省略す ることは出来ません #DEF TEST 00001111b ;f を 2進数(00000000b - 01111111b) で直接指定 'b' は 2進数であることを明示するためのものですが、 省略可能です #DEF TEST 'A' ;f を ASCIIキャラクタ(20h - 7Eh) で直接指定 ' で囲む必要がある ' 自身も ''' で指定可能です #DEF TEST *+ ;f を自動割付し、割り付け用アドレス・ポインタを ;インクリメントする #DEF TEST * ;f を自動割付し、割り付けするがアドレス・ポインタは ;インクリメントしない 3) レジスタ・ファイル・ビット指定 b の記述方法 #DEF DC 1 ;b を数値(0 - 7)で直接指定 #BITDEF STATUS.DC 03h 1 #BITDEF STATUS.DC 00000011b 1 #BITDEF TEST.A *+ 1 ;自動割付時でもビット指定は必要 #BITDEF TEST.A * 1 ;同上 4) 宛先指定子 d の記述方法 #DEF WREG 0 ;d を 1 又は 0 で直接指定 5) 定数 k の記述方法 #ORG 128 ;#ORG では k を 10進数 で指定 #MAXROMSIZE 1024 ;#MAXOMSIZE では k を 10進数 で指定 #DEF TEST 0Fh ;k を 16進数(00h - FFh) で直接指定 'h' は 16進数であることを明示するためのものですが、 省略可能です #DEF TEST .16 ;k を 10進数(.0 - .255) で直接指定 '.' は 10進数であることを明示するためのもので省略す ることは出来ません #DEF TEST 00001111b ;k を 2進数(00000000b - 11111111b) で直接指定 'b' は 2進数であることを明示するためのものですが、 省略可能です #DEF TEST 'A' ;k を ASCIIキャラクタ(20h - 7Eh) で直接指定 ' で囲む必要がある ' 自身も ''' で指定可能です 6) (ビット)定義名/ラベル名 name の記述方法 name は 31文字以内で、大文字('A'等)と小文字('a'等)は区別する。 name に使用できない文字は (スペース) (,) の二文字 (ビット)定義名とラベル名は重複できません ただし、ローカル・ラベルは 0〜9 のみで、重複は許されます。 7) アドレス addres の記述方法 #CNF 2000 000000000110011 ;#CNF では addres は 16進数(2000h - 2007h) で 指定 コンフィグレーション領域のメモリ・マップは下 記の通り 2000h - 2003h :ID情報格納領域 2007h :コンフィグレーション・ヒューズ 注)アドレスが小さいものから順に記述すること 16進数を明示する 'h' は使わないこと #DAT 1F 41h ;#DAT では addres は 16進数(00h - 3Fh) で指定 注)アドレスが小さいものから順に記述すること 16進数を明示する 'h' は使わないこと 8) データ data の記述方法 #CNF 2000 00000000110011 ;#CNF では data は 2進数14bit長で指定 注)2進数を明示する 'b' は使わないこと #DAT 1F 41h ;data を 16進数(00h - FFh) で直接指定 'h' は 16進数であることを明示するためのもので すが、省略可能です #DAT 1F .65 ;data を 10進数(.0 - .255) で直接指定 '.' は 10進数であることを明示するためのもので 省略することは出来ません #DAT 1F 01000001b ;data を 2進数(00000000b - 11111111b)で直接指定 'b' は 2進数であることを明示するためのものです が、省略可能です #DAT 1F 'A' ;data を ASCIIキャラクタ(20h - 7Eh) で直接指定 ' で囲む必要がある ' 自身も ''' で指定可能です 5.マクロ機能(マクロ命令と呼びます) 0) 凡例 W ;W レジスタ、小文字'w'は不可 reg. , reg.1 , reg.2 ;#DEF で定義された定義名 bit. , bit.1 , bit.2 ;#BITDEF で定義されたビット定義名 lit. ;#DEF で定義された定義名、または数値 ;例) ; #def lit. 10h ; W += #lit. ; W += #10h + ;加算 - ;減算 | ;論理OR & ;論理AND ^ ;論理XOR >> ;右シフト << ;左シフト ~ ;コンプリメント 1) 代入文 ;(展開に要するコード数),影響を受ける フラグ、レジスタ reg. = #lit. ;(2),W reg. = W ;(1) reg.1 = reg.2 ;(2),Z,W W = #lit. ;(1),W W = reg. ;(1),W 2) 二項演算 reg.1 = reg.2 + reg.3 ;(3),C,DC,Z,W reg.1 = reg.2 - reg.3 ;(3),C,DC,Z,W reg.1 = reg.2 | reg.3 ;(3),Z,W reg.1 = reg.2 & reg.3 ;(3),Z,W reg.1 = reg.2 ^ reg.3 ;(3),Z,W reg.1 = reg.1 + reg.3 ;(2),C,DC,Z,W reg.1 = reg.1 - reg.3 ;(2),C,DC,Z,W reg.1 = reg.1 | reg.3 ;(2),Z,W reg.1 = reg.1 & reg.3 ;(2),Z,W reg.1 = reg.1 ^ reg.3 ;(2),Z,W reg.1 = reg.2 + reg.1 ;(2),C,DC,Z,W reg.1 = reg.2 - reg.1 ;(3),C,DC,Z,W reg.1 = reg.2 | reg.1 ;(2),Z,W reg.1 = reg.2 & reg.1 ;(2),Z,W reg.1 = reg.2 ^ reg.1 ;(2),Z,W reg.1 = reg.2 + #lit. ;(3),C,DC,Z,W reg.1 = reg.2 - #lit. ;(3),C,DC,Z,W reg.1 = reg.2 | #lit. ;(3),Z,W reg.1 = reg.2 & #lit. ;(3),Z,W reg.1 = reg.2 ^ #lit. ;(3),Z,W reg.1 = reg.1 + #lit. ;(2),C,DC,Z,W reg.1 = reg.1 - #lit. ;(2),C,DC,Z,W reg.1 = reg.1 | #lit. ;(2),Z,W reg.1 = reg.1 & #lit. ;(2),Z,W reg.1 = reg.1 ^ #lit. ;(2),Z,W reg.1 = reg.2 + W ;(2),C,DC,Z,W reg.1 = reg.2 - W ;(2),C,DC,Z,W reg.1 = reg.2 | W ;(2),Z,W reg.1 = reg.2 & W ;(2),Z,W reg.1 = reg.2 ^ W ;(2),Z,W reg.1 = reg.1 + W ;(1),C,DC,Z reg.1 = reg.1 - W ;(1),C,DC,Z reg.1 = reg.1 | W ;(1),Z reg.1 = reg.1 & W ;(1),Z reg.1 = reg.1 ^ W ;(1),Z reg.1 = #lit. + reg.2 ;(3),C,DC,Z,W reg.1 = #lit. - reg.2 ;(3),C,DC,Z,W reg.1 = #lit. | reg.2 ;(3),Z,W reg.1 = #lit. & reg.2 ;(3),Z,W reg.1 = #lit. ^ reg.2 ;(3),Z,W reg.1 = #lit. + reg.1 ;(2),C,DC,Z,W reg.1 = #lit. - reg.1 ;(3),C,DC,Z,W reg.1 = #lit. | reg.1 ;(2),Z,W reg.1 = #lit. & reg.1 ;(2),Z,W reg.1 = #lit. ^ reg.1 ;(2),Z,W reg. = #lit. + W ;(2),C,DC,Z,W reg. = #lit. - W ;(2),C,DC,Z,W reg. = #lit. | W ;(2),Z,W reg. = #lit. & W ;(2),Z,W reg. = #lit. ^ W ;(2),Z,W reg.1 = W + reg.2 ;(2),C,DC,Z,W reg.1 = W - reg.2 ;(3),C,DC,Z,W reg.1 = W | reg.2 ;(2),Z,W reg.1 = W & reg.2 ;(2),Z,W reg.1 = W ^ reg.2 ;(2),Z,W reg.1 = W + reg.1 ;(1),C,DC,Z reg.1 = W - reg.1 ;(3),C,DC,Z reg.1 = W | reg.1 ;(1),Z reg.1 = W & reg.1 ;(1),Z reg.1 = W ^ reg.1 ;(1),Z reg. = W + #lit. ;(2),C,DC,Z,W reg. = W - #lit. ;(3),C,DC,Z,W reg. = W | #lit. ;(2),Z,W reg. = W & #lit. ;(2),Z,W reg. = W ^ #lit. ;(2),Z,W W = reg.1 + reg.2 ;(2),C,DC,Z,W W = reg.1 - reg.2 ;(2),C,DC,Z,W W = reg.1 | reg.2 ;(2),Z,W W = reg.1 & reg.2 ;(2),Z,W W = reg.1 ^ reg.2 ;(2),Z,W W = reg. + #lit. ;(2),C,DC,Z,W W = reg. - #lit. ;(2),C,DC,Z,W W = reg. | #lit. ;(2),Z,W W = reg. & #lit. ;(2),Z,W W = reg. ^ #lit. ;(2),Z,W W = reg. + W ;(1),C,DC,Z,W W = reg. - W ;(1),C,DC,Z,W W = reg. | W ;(1),Z,W W = reg. & W ;(1),Z,W W = reg. ^ W ;(1),Z,W W = #lit. + reg. ;(2),C,DC,Z,W W = #lit. - reg. ;(2),C,DC,Z,W W = #lit. | reg. ;(2),Z,W W = #lit. & reg. ;(2),Z,W W = #lit. ^ reg. ;(2),Z,W W = #lit. + W ;(1),C,DC,Z,W W = #lit. - W ;(1),C,DC,Z,W W = #lit. | W ;(1),Z,W W = #lit. & W ;(1),Z,W W = #lit. ^ W ;(1),Z,W W = W + reg. ;(1),C,DC,Z,W /* W = W - reg. 使用不可 W = W | reg. ;(1),Z,W W = W & reg. ;(1),Z,W W = W ^ reg. ;(1),Z,W W = W + #lit. ;(1),C,DC,Z,W /* W = W - #lit. 使用不可 W = W | #lit. ;(1),Z,W W = W & #lit. ;(1),Z,W W = W ^ #lit. ;(1),Z,W 3) 演算代入文 reg.1 += reg.2 ;(2),C,DC,Z,W reg.1 -= reg.2 ;(2),C,DC,Z,W reg.1 |= reg.2 ;(2),Z,W reg.1 &= reg.2 ;(2),Z,W reg.1 ^= reg.2 ;(2),Z,W reg. += #lit. ;(2),C,DC,Z,W reg. -= #lit. ;(2),C,DC,Z,W reg. |= #lit. ;(2),Z,W reg. &= #lit. ;(2),Z,W reg. ^= #lit. ;(2),Z,W reg. += W ;(1),C,DC,Z reg. -= W ;(1),C,DC,Z reg. |= W ;(1),Z reg. &= W ;(1),Z reg. ^= W ;(1),Z W += reg. ;(1),C,DC,Z,W /* W -= reg. 使用不可 W |= reg. ;(1),Z,W W &= reg. ;(1),Z,W W ^= reg. ;(1),Z,W W += #lit. ;(1),C,DC,Z,W /* W -= #lit. 使用不可 W |= #lit. ;(1),Z,W W &= #lit. ;(1),Z,W W ^= #lit. ;(1),Z,W 4) コンプリメント演算 ~reg. ;(1),Z W = ~reg. ;(1),Z,W reg.1 = ~reg.2 ;(2),Z,W reg.1 = ~reg.1 ;(1),Z ~W ;(1),C,DC,Z,W reg. = ~W ;(2),Z W = ~W ;(1),C,DC,Z,W 5) シフト演算 /* rrf (シフト数 n は #1 to #7) reg.1 = reg.2 >> #1 ;(3+n),C,W reg.1 = reg.1 >> #1 ;(n),C reg. >>= #1 ;(n),C /* rlf (シフト数 n は #1 to #7) reg.1 = reg.2 << #1 ;(3+n),C,W reg.1 = reg.1 << #1 ;(n),C reg. <<= #1 ;(n),C 6) bit 代入文 #0 -> bit.1 ;(1) #1 -> bit.1 ;(1) bit.1 -> bit.2 ;(4) 7) ゼロ・チェック文 /* reg. のチェック reg. ;(1),Z /* W のチェック W ;(1),Z 8) 組み込み関数 /* リターン return() ;(1) return( #lit. ) ;(1) /* 上位4ビットと下位4ビットの入れ替え swap ( reg.1 ) ;(1) reg.1 = swap ( reg.2 ) ;(2),W reg.1 = swap ( reg.1 ) ;(1) W = swap ( reg. ) ;(1) /* push (W -> reg.1 , status -> reg.2) push ( reg.1 , reg.2 ) ;(4),W /* pop (reg.1 -> W , reg.2 -> status) pop (reg.1 , reg.2 ) ;(3),W 9) if 文 a) #BITDEF で定義したファイル・レジスタのビットを使う場合 if ( bit. == #0 ) { ;bit. が 0 の場合、code1 を実行 code1 ; 1 code2 } else { code2 } 勿論、else 文が無いような、 if ( bit. == #0 ) { code } も可能です。 また、codeに一つのコードを書く場合で、else を使わない場合に限り if ( bit. == #0 ) code のような書き方も可能です また、if のネスティングも制限はありません if ( bit. == #0 ) { if ( bit.1 == #0 ) { code1 if (bit.2 == #1 ) { code2 } else { code3 } } } else { code2 } 注1)上記、code,code1,code2 には、アセンブラのニモニック、ラベル、 疑似命令、上記1)-8)のマクロ命令を書くことが可能です。 ただし、ラベルや疑似命令だけを記述することはできません。 if ( bit. == #0 ) { #lbl loop ;#LBL しかないので、不可 } 注2)()内の記述順序は、 if (bit. == #0) のようにして下さい。 if (#0 == bit.) は不可です 注3)比較可能な定数は、 if (bit. == #0) ;if (bit. == #00) も可 if (bit. == #1) ;if (bit. == #01) も可 のみで、#0 と #1 のみです。また、 #bitdef bit.2 0 if (bit. == #bit ) のように、ビット定義名を使うことはできません。 注4){}の付け方には制限はありません、下記の例は全て可能です if (bit. == #0) { code1 } else { code2 } if (bit. == #0) { code1 } else { code2 } if (bit. == #0) { code1 } else { code2 } if (bit. == #0) { code1 } else { code2 } if (bit. == #0) { code1 } else { code2 } 注5)'{',else,'}'のある行には、if()内を除きコードは書けません (コメント文字は可能) if (bit. == #0 ) { code } ;不可 if (bit. == #0 ) { code } ;不可 b) #DEF で定義したファイル・レジスタを使う場合 if ((code) == #00) のように、if()内の()内に、マクロ命令を書き、STATUSレジスタの ZERO,CARYフラグの変化を検出することにより行います。 code には上記1)-8)の単一のマクロ命令のみが可能で、アセンブラの ニモニックや疑似命令は書くことができません if ( ( reg. = #lit. + W ) == #00 ) { ;可 if ( ( movlw #lit. ) == #00 ) { ;不可 フラグの変化は下記の組み合わせのみです if ( (code) == #00 ) ;ZEROフラグ == 1 if ( (code) != #00 ) ; == 0 if ( (code) > #FF ) ;CARYフラグ == 1 加算コードで使用 if ( (code) <= #FF ) ; == 0 〃 if ( (code) >= #00 ) ;CARYフラグ == 1 減算コードで使用 if ( (code) < #00 ) ; == 0 〃 上記以外の組み合わせは不可です。 注1)上記の code で 対応するフラグが変化しない場合には、 アセンブル時に注意が表示されます。 他の、注意事項については、a)を参照下さい。 ■ マクロ機能の注意 1) W レジスタの変化に注意 reg.1 = reg.2 + reg.3 のように、W を明示的に含まない場合でも、W レジスタが作業レジスタ として使われる場合がありますから、注意して下さい。 ■ その他 本プログラムはフリーソフトウエアです。 転載は各自の責任で行って下さい。 Cソースは Turbo C++ Version 1.01 でコンパイルしました。