From: j8takagi Date: Sat, 2 Jun 2018 16:23:00 +0000 (+0900) Subject: disassembleコマンドを追加 X-Git-Tag: v3.0p1 X-Git-Url: http://j8takagi.net/cgi-bin/gitweb.cgi?p=YACASL2.git;a=commitdiff_plain;h=4d98d132e119aa98dd7abcb76b6a96ae4723f274;hp=03e322484530da78d796401413d9f5f493d95345 disassembleコマンドを追加 --- diff --git a/.gitignore b/.gitignore index 123260b..e2eadfc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,10 @@ /casl2 /comet2 /dumpword +/disassemble *.o +!as/sample/hello.o +!as/sample/sum_10.o *~ GPATH GRTAGS diff --git a/Makefile b/Makefile index 80f8a82..a16c13c 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ clean src-clean gtags-clean \ test-clean doc-clean doc_inner-clean -CMD := casl2 comet2 dumpword +CMD := casl2 comet2 dumpword disassemble CAT := cat CP := cp diff --git a/VERSION b/VERSION index b5c41d8..8078fca 100644 --- a/VERSION +++ b/VERSION @@ -1,2 +1,2 @@ -v0.2p45 +v0.3 diff --git a/as/sample/hello.o b/as/sample/hello.o new file mode 100644 index 0000000..ada8b01 Binary files /dev/null and b/as/sample/hello.o differ diff --git a/as/sample/hello.o.casl b/as/sample/hello.o.casl new file mode 100644 index 0000000..77c1e3f --- /dev/null +++ b/as/sample/hello.o.casl @@ -0,0 +1,30 @@ +MAIN START + PUSH #0000,GR1 ; #0000 + PUSH #0000,GR2 ; #0002 + LAD GR1,#0013 ; #0004 + LAD GR2,#0020 ; #0006 + SVC #0002 ; #0008 + LAD GR1,#0021 ; #000A + LAD GR2,#0022 ; #000C + SVC #0002 ; #000E + POP GR2 ; #0010 + POP GR1 ; #0011 + RET ; #0012 + DC 72 ; #0013 + DC 101 ; #0014 + DC 108 ; #0015 + DC 108 ; #0016 + DC 111 ; #0017 + DC 44 ; #0018 + DC 32 ; #0019 + DC 87 ; #001A + DC 111 ; #001B + DC 114 ; #001C + DC 108 ; #001D + DC 100 ; #001E + DC 33 ; #001F + DC 13 ; #0020 + DC 10 ; #0021 + DC 1 ; #0022 + DC 1 ; #0023 + END diff --git a/as/sample/sum_10.o b/as/sample/sum_10.o new file mode 100644 index 0000000..3f09454 Binary files /dev/null and b/as/sample/sum_10.o differ diff --git a/as/sample/sum_10.o.casl b/as/sample/sum_10.o.casl new file mode 100644 index 0000000..f1bd9f2 --- /dev/null +++ b/as/sample/sum_10.o.casl @@ -0,0 +1,16 @@ +MAIN START + PUSH #0000,GR1 ; #0000 + LAD GR0,#0000 ; #0002 + LD GR1,#0011 ; #0004 + ADDL GR0,GR1 ; #0006 + ADDL GR1,#0013 ; #0007 + CPL GR1,#0012 ; #0009 + JPL #000F ; #000B + JUMP #0006 ; #000D + POP GR1 ; #000F + RET ; #0010 + DC 1 ; #0011 + DC 10 ; #0012 + DC 1 ; #0013 + DC 1 ; #0014 + END diff --git a/include/struct.h b/include/struct.h index 54a2418..ee59634 100644 --- a/include/struct.h +++ b/include/struct.h @@ -156,6 +156,16 @@ bool create_code_cmdtype(); */ const void (*getcmdptr(WORD code)); +/** + * 命令コードから命令のタイプを返す + */ +CMDTYPE getcmdtype(WORD code); + +/** + * 命令コードから命令の名前を返す + */ +char *getcmdname(WORD code); + /** * コードがキーの命令ハッシュ表を解放する */ diff --git a/src/.gitignore b/src/.gitignore index 5303710..a13272b 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -5,3 +5,4 @@ tags casl2 comet2 dumpword +disassemble \ No newline at end of file diff --git a/src/Makefile b/src/Makefile index f1ae419..60d447e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,5 +1,5 @@ # ソースファイル。グループに分類 -CMDOBJ := casl2 comet2 dumpword +CMDOBJ := casl2 comet2 dumpword disassemble COMMONOBJ := word cmem cerr CASL2OBJ := struct hash ASOBJ := assemble token label @@ -31,6 +31,8 @@ comet2: $(addsuffix .o,comet2 $(COMMONOBJ) $(CASL2OBJ) $(EXECOBJ)) dumpword: $(addsuffix .o,dumpword $(COMMONOBJ)) +disassemble:$(addsuffix .o,disassemble $(COMMONOBJ) $(CASL2OBJ) $(EXECOBJ)) + # .dファイルからヘッダファイルの依存関係を取得する # tags、check、clean、.d で終わるターゲットの場合は除く NODEP := %tags %check %clean %.d diff --git a/src/disassemble.c b/src/disassemble.c new file mode 100644 index 0000000..7aef8bd --- /dev/null +++ b/src/disassemble.c @@ -0,0 +1,127 @@ +#include +#include +#define _GNU_SOURCE +#include +#include + +#include "exec.h" +#include "cmem.h" +#include "cerr.h" +#include "package.h" + +char *grstr(WORD word) +{ + char *str; + str = (char *)malloc(4); + sprintf(str, "GR%d", word); + return str; +} + +bool disassemble(const char *file) +{ + FILE *fp; + bool stat = true; + int i = 0; + WORD w, cmd, r, x, r1, r2, adr; + CMDTYPE type = 0; + char *cmdname; + + assert(file != NULL); + if((fp = fopen(file, "rb")) == NULL) { + perror(file); + return false; + } + + create_code_cmdtype(); /* 命令のコードとタイプがキーのハッシュ表を作成 */ + + fprintf(stdout, "MAIN\tSTART\n"); + for( ; !feof(fp); ) { + fread(&w, sizeof(WORD), 1, fp); + cmd = w & 0xFF00; + cmdname = getcmdname(cmd); + if(cmd == 0xFF00 || (w != 0 && cmd == 0x0000)) { + fprintf(stdout, "\tDC\t%d\t\t; #%04X", w, i++); + } else if((type = getcmdtype(cmd)) == R_ADR_X || type == ADR_X) { + fread(&adr, sizeof(WORD), 1, fp); + fprintf(stdout, "\t%s\t", cmdname); + if(type == R_ADR_X) { + r = (w & 0x00F0) >> 4; + fprintf(stdout, "%s,", grstr(r)); + } + fprintf(stdout, "#%04X", adr); + if((x = w & 0x000F) != 0) { + fprintf(stdout, ",%s", grstr(x)); + } + fprintf(stdout, "\t\t; #%04X", i); + i += 2; + } else { + fprintf(stdout, "\t%s", cmdname); + if(type == R1_R2) { + r1 = (w & 0x00F0) >> 4; + r2 = w & 0x000F; + fprintf(stdout, "\t%s,%s", grstr(r1), grstr(r2)); + } else if(type == R_) { + r = (w & 0x00F0) >> 4; + fprintf(stdout, "\t%s", grstr(r)); + } + fprintf(stdout, "\t\t; #%04X", i++); + } + fprintf(stdout, "\n"); + } + fprintf(stdout, "\tEND\n"); + free_code_cmdtype(); + return stat; +} + +/** + * disassembleコマンドのオプション + */ +static struct option longopts[] = { + {"version", no_argument, NULL, 'v' }, + {"help", no_argument, NULL, 'h'}, + {0, 0, 0, 0}, +}; + +/** + * @brief disassembleコマンドのメイン + * + * @return 正常終了時は0、異常終了時は1 + * + * @param argc コマンドライン引数の数 + * @param *argv[] コマンドライン引数の配列 + */ +int main(int argc, char *argv[]) +{ + int opt, stat = 0; + const char *version = PACKAGE_VERSION, *cmdversion = "disassemble of YACASL2 version %s\n"; + const char *usage = "Usage: %s [-vh] FILE\n"; + + cerr_init(); + addcerrlist_load(); + addcerrlist_exec(); + + /* オプションの処理 */ + while((opt = getopt_long(argc, argv, "vh", longopts, NULL)) != -1) { + switch(opt) { + case 'v': + fprintf(stdout, cmdversion, version); + return 0; + case 'h': + fprintf(stdout, usage, argv[0]); + return 0; + case '?': + fprintf(stderr, usage, argv[0]); + exit(1); + } + } + if(argv[optind] == NULL) { + setcerr(211, ""); /* object file not specified */ + fprintf(stderr, "disassemble error - %d: %s\n", cerr->num, cerr->msg); + exit(1); + } + disassemble(argv[optind]); /* プログラム実行 */ + stat = (cerr->num == 0) ? 0 : 1; + /* エラーの解放 */ + freecerr(); + return stat; +} diff --git a/src/exec.c b/src/exec.c index a6c7edc..a447aa7 100644 --- a/src/exec.c +++ b/src/exec.c @@ -237,7 +237,7 @@ bool loadassemble(const char *file) bool stat = true; assert(file != NULL); - if((fp = fopen(file, "r")) == NULL) { + if((fp = fopen(file, "rb")) == NULL) { perror(file); return false; } diff --git a/src/struct.c b/src/struct.c index 981409a..f0f705b 100644 --- a/src/struct.c +++ b/src/struct.c @@ -209,10 +209,27 @@ const void (*getcmdptr(WORD code)) return ptr; } +/** + * 命令コードから命令のタイプを返す + */ +CMDTYPE getcmdtype(WORD code) +{ + CMDTAB *t; + CMDTYPE type = 0; + + for(t = code_cmdtype[hash_code(code)]; t != NULL; t = t->next) { + if(code == t->cmd->code) { + type = t->cmd->type; + break; + } + } + return type; +} + /** * 命令コードから命令の名前を返す */ -char (*getcmdname(WORD code)) +char *getcmdname(WORD code) { CMDTAB *t; char *cmd = NULL; diff --git a/test/system/disassemble/Define.mk b/test/system/disassemble/Define.mk new file mode 120000 index 0000000..b4a58e1 --- /dev/null +++ b/test/system/disassemble/Define.mk @@ -0,0 +1 @@ +../../template/Define.mk \ No newline at end of file diff --git a/test/system/disassemble/Makefile b/test/system/disassemble/Makefile new file mode 120000 index 0000000..4f4e7b0 --- /dev/null +++ b/test/system/disassemble/Makefile @@ -0,0 +1 @@ +../../template/Group.mk \ No newline at end of file diff --git a/test/system/disassemble/Test.mk b/test/system/disassemble/Test.mk new file mode 120000 index 0000000..ada05aa --- /dev/null +++ b/test/system/disassemble/Test.mk @@ -0,0 +1 @@ +../../template/Test.mk \ No newline at end of file diff --git a/test/system/disassemble/sum_10/0.txt b/test/system/disassemble/sum_10/0.txt new file mode 100644 index 0000000..f1bd9f2 --- /dev/null +++ b/test/system/disassemble/sum_10/0.txt @@ -0,0 +1,16 @@ +MAIN START + PUSH #0000,GR1 ; #0000 + LAD GR0,#0000 ; #0002 + LD GR1,#0011 ; #0004 + ADDL GR0,GR1 ; #0006 + ADDL GR1,#0013 ; #0007 + CPL GR1,#0012 ; #0009 + JPL #000F ; #000B + JUMP #0006 ; #000D + POP GR1 ; #000F + RET ; #0010 + DC 1 ; #0011 + DC 10 ; #0012 + DC 1 ; #0013 + DC 1 ; #0014 + END diff --git a/test/system/disassemble/sum_10/Makefile b/test/system/disassemble/sum_10/Makefile new file mode 100644 index 0000000..b6dac59 --- /dev/null +++ b/test/system/disassemble/sum_10/Makefile @@ -0,0 +1,2 @@ +include ../Define.mk +include ../Test.mk diff --git a/test/system/disassemble/sum_10/cmd b/test/system/disassemble/sum_10/cmd new file mode 100755 index 0000000..879a760 --- /dev/null +++ b/test/system/disassemble/sum_10/cmd @@ -0,0 +1 @@ +../../../../disassemble ../../../../as/sample/sum_10.o