debug用関数を作る

※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。

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 もご覧ください。