debug用関数を作る

「debug用関数を作る」の編集履歴(バックアップ)一覧はこちら

debug用関数を作る」(2015/09/06 (日) 14:51:09) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

debug用関数を作る アセンブラやCを使っているとデバックがとても難しい。 そこでDOSデバッカがなくとも使える簡易型のデバック表示機能を作る。 使いかたはソースコード中でデバックしたい場所に関数を書いて実行すればよい。 Cプログラムなどからアセンブラなどを呼び出す場合のデバックに使うと便利だ。 DOS1/2だけでなくCPM汎用なので様々な機種で動作する。 この機能が呼ばれるとCPU状態をメモリに保存しデバック表示するとともに コンピュータの実行を停止する。 CPU状態の保存箇所はデフォルトでメモリアドレスの0xC000となる。MSX以外の ハードではアドレスを変えて使うことも可能だ。 アセンブラのソースコード部分を工夫すればsdcc以外でもビルドできるかもしれない。 stopdebug.asm ; _stopdebugtrace:: ; di ;disable interrupt ; ld (0xC000),a ;save registers ; ld (0xC002),bc ld (0xC004),de ld (0xC006),hl ; ld (0xC008),ix ld (0xC00a),iy ; ld (0xC00c),sp ; ei ret ; debug.c #include <stdio.h> extern void stopdebugtrace(); //extern void cls(); void debugdump(); //このソースはdebug機能サンプルです void main(void){ //asmで書かれたコードで実行中レジスタを保存する //デバックしたいコードラインの直前や直後にこの関数を書くこと stopdebugtrace(); //debug結果を表示 debugdump(); //割り込み停止、実行を止める __asm DI HALT __endasm; while(1); } void debugdump(void){ unsigned char * reg_a=(unsigned char *)0xC000; unsigned int * reg_bc=(unsigned int *)0xC002; unsigned int * reg_de=(unsigned int *)0xC004; unsigned int * reg_hl=(unsigned int *)0xC006; unsigned int * reg_ix=(unsigned int *)0xC008; unsigned int * reg_iy=(unsigned int *)0xC00a; unsigned int * reg_sp=(unsigned int *)0xC00c; unsigned int i; unsigned char *p_stack; // cls(); printf("*** STOP (HALT_DUMP_CPU_DEBUG) \r\n"); printf("\r\n"); printf("A problem has been detected\r\n"); printf("If this is the first time you've seen this Stop debug screen,\r\n"); printf("Press RESET to restart your computer.\r\n\r\n"); // printf("Techincal information:\r\n"); printf("REG: A=%02x BC=%04x DE=%04x \r\n",*reg_a, *reg_bc, *reg_de); printf(" HL=%04x IX=%04x IY=%04x SP=%x",*reg_hl, *reg_ix, *reg_iy, *reg_sp); p_stack=(unsigned char *)*reg_sp; printf(" PC=%02x%02x \r\n\r\n",p_stack[1],p_stack[0]); printf("STACK(%x): ",*reg_sp); for(i=0; i<16; i++){ printf("%02x ",p_stack[i]); } printf("\r\n"); } 実行結果画面 *** STOP (HALT_DUMP_CPU_DEBUG) A problem has been detected If this is the first time you've seen this Stop debug screen, Press RESET to restart your computer. Techincal information: REG: A=00 BC=0000 DE=0000 HL=0000 IX=0000 IY=0000 SP=fcfc PC=0106 STACK(fcfc): 06 01 00 fd 76 00 00 00 00 00 00 00 00 00 00 00
debug用関数を作る アセンブラやCを使っているとデバックがとても難しい。 そこでDOSデバッカがなくとも使える簡易型のデバック表示機能を作る。 使いかたはソースコード中でデバックしたい場所に関数を書いて実行すればよい。 Cプログラムなどからアセンブラなどを呼び出す場合のデバックに使うと便利だ。 DOS1/2だけでなくCPM汎用なので様々な機種で動作する。 この機能が呼ばれるとCPU状態をメモリに保存しデバック表示するとともに コンピュータの実行を停止する。 CPU状態の保存箇所はデフォルトでメモリアドレスの0xC000となる。MSX以外の ハードではアドレスを変えて使うことも可能だ。 アセンブラのソースコード部分を工夫すればsdcc以外でもビルドできるかもしれない。 stopdebug.asm ; _stopdebugtrace:: ; di ;disable interrupt ; ld (0xC000),a ;save registers ; ld (0xC002),bc ld (0xC004),de ld (0xC006),hl ; ld (0xC008),ix ld (0xC00a),iy ; ld (0xC00c),sp ; ei ret ; debug.c #include <stdio.h> extern void stopdebugtrace(); //extern void cls(); void debugdump(); //このソースはdebug機能サンプルです void main(void){ //asmで書かれたコードで実行中レジスタを保存する //デバックしたいコードラインの直前や直後にこの関数を書くこと stopdebugtrace(); //debug結果を表示 debugdump(); //割り込み停止、実行を止める __asm DI HALT __endasm; while(1); } void debugdump(void){ unsigned char * reg_a=(unsigned char *)0xC000; unsigned int * reg_bc=(unsigned int *)0xC002; unsigned int * reg_de=(unsigned int *)0xC004; unsigned int * reg_hl=(unsigned int *)0xC006; unsigned int * reg_ix=(unsigned int *)0xC008; unsigned int * reg_iy=(unsigned int *)0xC00a; unsigned int * reg_sp=(unsigned int *)0xC00c; unsigned int i; unsigned char *p_stack; // cls(); printf("*** STOP (HALT_DUMP_CPU_DEBUG) \r\n"); printf("\r\n"); printf("A problem has been detected\r\n"); printf("If this is the first time you've seen this Stop debug screen,\r\n"); printf("Press RESET to restart your computer.\r\n\r\n"); // printf("Techincal information:\r\n"); printf("REG: A=%02x BC=%04x DE=%04x \r\n",*reg_a, *reg_bc, *reg_de); printf(" HL=%04x IX=%04x IY=%04x SP=%x",*reg_hl, *reg_ix, *reg_iy, *reg_sp); p_stack=(unsigned char *)*reg_sp; printf(" PC=%02x%02x \r\n\r\n",p_stack[1],p_stack[0]); printf("STACK(%x): ",*reg_sp); for(i=0; i<16; i++){ printf("%02x ",p_stack[i]); } printf("\r\n"); } 実行結果画面 *** STOP (HALT_DUMP_CPU_DEBUG) A problem has been detected If this is the first time you've seen this Stop debug screen, Press RESET to restart your computer. Techincal information: REG: A=00 BC=0000 DE=0000 HL=0000 IX=0000 IY=0000 SP=fcfc PC=0106 STACK(fcfc): 06 01 00 fd 76 00 00 00 00 00 00 00 00 00 00 00 -メモリのダンプ CPUレジスタをダンプして停止するほかにもメモリをダンプして停止することもできる。 こちらはC言語だけで実装可能だ。デバックした箇所でメモリアドレスを指定して使う。 #include <stdio.h> void memdump(unsigned int); void main(void){ //コードライン中ダンプするタイミングでアドレス指定し関数を実行 memdump(0x0100); //割り込み停止し実行を止める。 __asm DI HALT __endasm; while(1); } void memdump(unsigned int address){ unsigned int i; unsigned int j; unsigned char *p_stack; // cls(); printf("*** STOP (HALT_DUMP_MEMORY) \r\n"); printf("\r\n"); printf("A problem has been detected\r\n"); printf("If this is the first time you've seen this Stop debug screen,\r\n"); printf("Press RESET to restart your computer.\r\n\r\n"); // printf("Technical information:\r\n"); p_stack=(unsigned char *)address; printf("Address(%04x): \r\n",address); for(j=0; j<128; j=j+16){ for(i=0; i<16; i++){ printf("%02x ",p_stack[i+j]); } for(i=0; i<16; i++){ if (p_stack[i]>0x20) { printf("%c",p_stack[i+j]); } else { printf("."); } } printf("\r\n"); } } 実行結果 *** STOP (HALT_DUMP_MEMORY) A problem has been detected If this is the first time you've seen this Stop debug screen, Press RESET to restart your computer. Technical information: Address(0100): 21 00 01 e5 cd 0c 01 f1 f3 76 18 fe dd e5 dd 21 !..袁..v.ン袿! 00 00 dd 39 21 f8 ff 39 f9 21 56 02 e5 cd 82 03 ..9!..9・.袁・ 21 75 02 e3 cd 82 03 21 78 02 e3 cd 82 03 21 96 !..耋..!x.ヘ・!・ 02 e3 cd 82 03 21 d6 02 e3 cd 82 03 21 00 03 e3 ..・..耋.!・ cd 82 03 f1 dd 7e 04 dd 77 fa dd 7e 05 dd 77 fb ヘ....ンw・~ンw・ dd 6e 04 dd 66 05 e5 21 19 03 e5 cd 82 03 f1 f1 ン..ンf..!.ヘ・ dd 36 fc 00 dd 36 fd 00 dd 7e fc d6 80 dd 7e fd ン..ン..ン~.ヨ€ン~ de 00 d2 51 02 dd 36 fe 00 dd 36 ff 00 dd 7e fe ゙..Q..ン.ン~

表示オプション

横に並べて表示:
変化行の前後のみ表示:
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。