From: j8takagi Date: Fri, 26 Jun 2026 15:01:16 +0000 (+0900) Subject: monitorで、逆アセンブル表示機能を追加し、デフォルト表示するように X-Git-Tag: v0.6p00~10 X-Git-Url: https://j8takagi.net/gitweb?a=commitdiff_plain;h=42640a98da573970ff78fd2538757b063cf6b45b;p=yacasl2.git monitorで、逆アセンブル表示機能を追加し、デフォルト表示するように https://claude.ai/share/6eb72216-cd19-4e32-9d59-b389e84d1c87 --- diff --git a/include/struct.h b/include/struct.h index 36de1be..9b8abb2 100644 --- a/include/struct.h +++ b/include/struct.h @@ -149,12 +149,13 @@ typedef struct { bool dump; /**<メモリの内容をステップごとに表示する場合はtrue */ WORD dump_start; /**<メモリの内容をステップごとに表示する場合の開始アドレス */ WORD dump_end; /**<メモリの内容をステップごとに表示する場合の終了アドレス */ + bool reverse; /**<逆アセンブルの結果をステップごとに表示する場合はtrue */ bool monitor; /**<モニターモードの場合はtrue */ bool step; /**<ステップ実行の場合はtrue */ } EXECMODE; /** - * @brief 実行モード: trace, logical, dump, monitor, step + * @brief 実行モード: trace, logical, dump, reverse, monitor, step */ extern EXECMODE execmode; @@ -239,3 +240,9 @@ CMDTYPE getcmdtype(WORD code); char *getcmdname(WORD code); #endif + +/** + * 命令コードから、命令語長を返す\n + * 無効な場合は0を返す + */ +WORD code2cmdwordlen(WORD code); diff --git a/src/comet2monitor.c b/src/comet2monitor.c index 338a2d0..299802d 100644 --- a/src/comet2monitor.c +++ b/src/comet2monitor.c @@ -12,6 +12,7 @@ static struct option longopts[] = { {"tracearithmetic", no_argument, NULL, 't'}, {"tracelogical", no_argument, NULL, 'T'}, {"dump", no_argument, NULL, 'd'}, + {"reverse", no_argument, NULL, 'r'}, {"memorysize", required_argument, NULL, 'M'}, {"clocks", required_argument, NULL, 'C'}, {"version", no_argument, NULL, 'v' }, @@ -47,7 +48,7 @@ int main(int argc, char *argv[]) int stat = 0; const char *version = PACKAGE_VERSION; const char *cmdversion = "comet2monitor: COMET II machine code monitor of YACASL2 version %s\n"; - const char *usage = "Usage: %s [-tTdvh] [-M ] [-C ] FILE\n"; + const char *usage = "Usage: %s [-tTdrvh] [-M ] [-C ] FILE\n"; /* エラーの定義 */ cerr_init(); @@ -55,8 +56,9 @@ int main(int argc, char *argv[]) addcerrlist_exec(); addcerrlist_comet2monitor(); + execmode.reverse = true; /* オプションの処理 */ - while((opt = getopt_long(argc, argv, "tTdM:C:vh", longopts, NULL)) != -1) { + while((opt = getopt_long(argc, argv, "tTdqM:C:vh", longopts, NULL)) != -1) { switch(opt) { case 't': execmode.trace = true; @@ -68,6 +70,9 @@ int main(int argc, char *argv[]) case 'd': execmode.dump = true; break; + case 'q': + execmode.reverse = false; + break; case 'M': if((memsize = memsize_str2word(optarg)) == 0) { goto comet2monitorfin; diff --git a/src/dump.c b/src/dump.c index a6c70d7..343cced 100644 --- a/src/dump.c +++ b/src/dump.c @@ -1,4 +1,6 @@ #include "exec.h" +#include "struct.h" +#include "disassemble.h" /* exec.hに定義された関数群 */ void dumpmemory(WORD start, WORD end) @@ -58,15 +60,23 @@ void dspregister() void dsp_trace_dump() { - if(execptr->stop == false && (execmode.dump || execmode.trace)) { /* traceまたはdumpオプション指定時、改行を出力 */ - if(execmode.trace) { /* traceオプション指定時、レジスタを出力 */ + if(execptr->stop == false && (execmode.dump == true || execmode.trace == true || execmode.reverse == true)) { /* traceまたはdumpオプション指定時、改行を出力 */ + if(sys->cpu->pr == execptr->start && execmode.reverse == true) { /* reverseオプション指定時、スタート時にプログラム全体を逆アセンブル */ + fprintf(stdout, "Disassemble::::\n"); + disassemble_memory(execptr->start, execptr->end); + } + if(execmode.trace == true) { /* traceオプション指定時、レジスタを出力 */ fprintf(stdout, "#%04X: Register::::\n", sys->cpu->pr); dspregister(); } - if(execmode.dump) { /* dumpオプション指定時、メモリを出力 */ + if(execmode.dump == true) { /* dumpオプション指定時、メモリを出力 */ fprintf(stdout, "#%04X: Memory::::\n", sys->cpu->pr); dumpmemory(execmode.dump_start, execmode.dump_end); } + if(execmode.reverse == true) { /* reverseオプション指定時、ステップごとに語長分を逆アセンブル */ + fprintf(stdout, "#%04X: Disassemble::::\n", sys->cpu->pr); + disassemble_memory(sys->cpu->pr, sys->cpu->pr + code2cmdwordlen(sys->memory[sys->cpu->pr] & 0xFF00) - 1); + } fprintf(stdout, "\n"); } } diff --git a/src/exec.c b/src/exec.c index e8f2f64..15df261 100644 --- a/src/exec.c +++ b/src/exec.c @@ -85,9 +85,9 @@ static CERR cerr_exec[] = { }; /** - * @brief 実行モード: trace, logical, dump, dump_start, dump_end, monitor, step + * @brief 実行モード: trace, logical, dump, dump_start, dump_end, reverse, monitor, step */ -EXECMODE execmode = {false, false, false, 0, 0xFFFF, false, false}; +EXECMODE execmode = {false, false, false, 0, 0xFFFF, false, false, false}; CLOCK clock_str2clock(const char *str) { long val = str2l_range(str, 1, LONG_MAX, "Clock"); diff --git a/src/monitor.c b/src/monitor.c index b742486..abbce7e 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -301,8 +301,14 @@ MONCMDTYPE monitorcmd(char *cmd, MONARGS *args) fprintf(stdout, "Quit: COMET II monitor\n"); cmdtype = MONQUIT; } else if(stracmp(cmd, 2, (char* []){"r", "reverse"})) { - if(args->argc == 2) { + if(args->argc > 0 && stracmp(args->argv[0], 2, (char* []){"a", "auto"})) { + execmode.reverse = true; + } else if(args->argc > 0 && stracmp(args->argv[0], 2, (char* []){"n", "noauto"})) { + execmode.reverse = false; + } else if(args->argc == 2) { disassemble_memory(nh2word(args->argv[0]), nh2word(args->argv[1])); + } else { + disassemble_memory(execptr->start, execptr->end); } } else if(stracmp(cmd, 1, (char* []){"reset"})) { fprintf(stdout, "Reset COMET II CPU.\n"); @@ -310,21 +316,15 @@ MONCMDTYPE monitorcmd(char *cmd, MONARGS *args) } else if(stracmp(cmd, 1, (char* []){"resetall"})) { fprintf(stdout, "Reset COMET II CPU and memory.\n"); comet2_resetall(); /* COMET II仮想マシンのCPUとメモリのリセット */ - } else if(stracmp(cmd, 2, (char* []){"t", "trace"})) { - if(args->argc > 0 && stracmp(args->argv[0], 2, (char* []){"a", "auto"})) { + } else if(stracmp(cmd, 2, (char* []){"t", "trace", "T", "tracelogical"})) { + if(stracmp(cmd, 2, (char* []){"t", "trace"})) { execmode.logical = false; - execmode.trace = true; - } else if(args->argc > 0 && stracmp(args->argv[0], 2, (char* []){"no", "noauto"})) { - execmode.trace = false; } else { - fprintf(stdout, "#%04X: Register::::\n", sys->cpu->pr); - dspregister(); + execmode.logical = true; } - } else if(stracmp(cmd, 2, (char* []){"T", "tracelogical"})) { if(args->argc > 0 && stracmp(args->argv[0], 2, (char* []){"a", "auto"})) { - execmode.logical = true; execmode.trace = true; - } else if(args->argc > 0 && stracmp(args->argv[0], 2, (char* []){"no", "noauto"})) { + } else if(args->argc > 0 && stracmp(args->argv[0], 2, (char* []){"n", "noauto"})) { execmode.trace = false; } else { fprintf(stdout, "#%04X: Register::::\n", sys->cpu->pr); @@ -340,10 +340,10 @@ MONCMDTYPE monitorcmd(char *cmd, MONARGS *args) fprintf(stdout, "q[uit] -- Quit running your program.\n"); fprintf(stdout, "reset -- Reset COMET II CPU.\n"); fprintf(stdout, "resetall -- Reset COMET II CPU and memory.\n"); - fprintf(stdout, "r[everse] -- Disassemble memory. `r[everse] .\n"); + fprintf(stdout, "r[everse] -- Disassemble memory. `r[everse] '. `r[everse] a[uto]/n[oauto]' set auto/noauto display.\n"); fprintf(stdout, "s[ave] -- Save object from the memory to a file. `s[ave] [ []]' if and is omitted, save the whole memory. if is omitted, save the memory after .\n"); fprintf(stdout, "t[race] -- Display CPU register. `t[race] a[uto]/n[oauto]' set auto/noauto display. \n"); - fprintf(stdout, "T[race] -- Display CPU register as logical value. `t[race] a[uto]/n[oauto]' set auto/noauto display. \n"); + fprintf(stdout, "T[race] -- Display CPU register as logical value. `t[race] a[uto]/n[oauto]' set auto/noauto display.\n"); fprintf(stdout, "?/h[elp] -- Display this help.\n"); } return cmdtype; diff --git a/src/struct.c b/src/struct.c index 70d0be7..6c695e7 100644 --- a/src/struct.c +++ b/src/struct.c @@ -183,16 +183,16 @@ WORD getcmdcode(const char *cmd, CMDTYPE type) WORD getcmdwordlen(const char *cmd, CMDTYPE type) { CMDTAB *p = NULL; - int l = 0; + int wl = 0; assert(cmd != NULL); for(p = cmdtab[HASH_CMDTYPE][hash_cmdtype(cmd, type)]; p != NULL; p = p->next) { if(strcmp(cmd, p->cmd->name) == 0 && type == p->cmd->type) { - l = p->cmd->wordlen; + wl = p->cmd->wordlen; break; } } - return l; + return wl; } /** @@ -263,6 +263,24 @@ char *getcmdname(WORD code) return cmd; } +/** + * 命令コードから、命令語長を返す\n + * 無効な場合は0を返す + */ +WORD code2cmdwordlen(WORD code) +{ + CMDTAB *t = NULL; + int wl = 0; + + for(t = cmdtab[HASH_CODE][hash_code(code)]; t != NULL; t = t->next) { + if(code == t->cmd->code) { + wl = t->cmd->wordlen; + break; + } + } + return wl; +} + /** * 汎用レジスタの番号からレジスタを表す文字列を返す */