disassembleコマンドを追加 v0.3
authorj8takagi <j8takagi@nifty.com>
Sat, 2 Jun 2018 16:23:00 +0000 (01:23 +0900)
committerj8takagi <j8takagi@nifty.com>
Sat, 2 Jun 2018 16:23:00 +0000 (01:23 +0900)
18 files changed:
.gitignore
Makefile
as/sample/hello.o [new file with mode: 0644]
as/sample/hello.o.casl [new file with mode: 0644]
as/sample/sum_10.o [new file with mode: 0644]
as/sample/sum_10.o.casl [new file with mode: 0644]
include/struct.h
src/.gitignore
src/Makefile
src/disassemble.c [new file with mode: 0644]
src/exec.c
src/struct.c
test/system/disassemble/Define.mk [new symlink]
test/system/disassemble/Makefile [new symlink]
test/system/disassemble/Test.mk [new symlink]
test/system/disassemble/sum_10/0.txt [new file with mode: 0644]
test/system/disassemble/sum_10/Makefile [new file with mode: 0644]
test/system/disassemble/sum_10/cmd [new file with mode: 0755]

index 123260b..e2eadfc 100644 (file)
@@ -1,7 +1,10 @@
 /casl2
 /comet2
 /dumpword
+/disassemble
 *.o
+!as/sample/hello.o
+!as/sample/sum_10.o
 *~
 GPATH
 GRTAGS
index 80f8a82..a16c13c 100644 (file)
--- 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/as/sample/hello.o b/as/sample/hello.o
new file mode 100644 (file)
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 (file)
index 0000000..77c1e3f
--- /dev/null
@@ -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 (file)
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 (file)
index 0000000..f1bd9f2
--- /dev/null
@@ -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
index 54a2418..ee59634 100644 (file)
@@ -156,6 +156,16 @@ bool create_code_cmdtype();
  */
 const void (*getcmdptr(WORD code));
 
+/**
+ * 命令コードから命令のタイプを返す
+ */
+CMDTYPE getcmdtype(WORD code);
+
+/**
+ * 命令コードから命令の名前を返す
+ */
+char *getcmdname(WORD code);
+
 /**
  * コードがキーの命令ハッシュ表を解放する
  */
index 5303710..a13272b 100644 (file)
@@ -5,3 +5,4 @@ tags
 casl2
 comet2
 dumpword
+disassemble
\ No newline at end of file
index f1ae419..60d447e 100644 (file)
@@ -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 (file)
index 0000000..7aef8bd
--- /dev/null
@@ -0,0 +1,127 @@
+#include <stdio.h>
+#include <stdlib.h>
+#define _GNU_SOURCE
+#include <getopt.h>
+#include <assert.h>
+
+#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;
+}
index a6c7edc..a447aa7 100644 (file)
@@ -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;
     }
index 981409a..f0f705b 100644 (file)
@@ -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 (symlink)
index 0000000..b4a58e1
--- /dev/null
@@ -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 (symlink)
index 0000000..4f4e7b0
--- /dev/null
@@ -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 (symlink)
index 0000000..ada05aa
--- /dev/null
@@ -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 (file)
index 0000000..f1bd9f2
--- /dev/null
@@ -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 (file)
index 0000000..b6dac59
--- /dev/null
@@ -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 (executable)
index 0000000..879a760
--- /dev/null
@@ -0,0 +1 @@
+../../../../disassemble ../../../../as/sample/sum_10.o