YACASL2
Loading...
Searching...
No Matches
disassemble.c
Go to the documentation of this file.
1#include "disassemble.h"
2
6int codecol = 32;
7
16WORD zero_data_cnt(const WORD *data, WORD wordlen);
17
26void disassemble_puts_code(int ascol, WORD pradr, int wordc, WORD wordv[]);
27
37void disassemble_cmd_adr_x(CMDTYPE cmdtype, const char *cmdname, WORD word, WORD adr, WORD pradr);
38
47void disassemble_cmd_r(CMDTYPE cmdtype, const char *cmdname, WORD word, WORD pradr);
48
55void disassemble_dc(WORD word, WORD pradr);
56
57void disassemble_puts_code(int ascol, WORD pradr, int wordc, WORD wordv[])
58{
59 for(int i = 0; i < codecol-ascol; i++){
60 fprintf(stdout, " ");
61 }
62 if(wordc == 1) {
63 fprintf(stdout, "; #%04X: #%04X", pradr, wordv[0]);
64 } else if(wordc == 2) {
65 fprintf(stdout, "; #%04X: #%04X #%04X", pradr, wordv[0], wordv[1]);
66 }
67}
68
69void disassemble_cmd_adr_x(CMDTYPE cmdtype, const char *cmdname, WORD word, WORD adr, WORD pradr)
70{
71 WORD x = 0;
72 char *g = NULL;
73 int cnt = 0;
74
75 cnt += fprintf(stdout, " %-7s ", cmdname);
76 if(cmdtype == R_ADR_X) {
77 cnt += fprintf(stdout, "%s,", g = grstr((word & 0x00F0) >> 4));
78 FREE(g);
79 }
80 cnt += fprintf(stdout, "#%04X", adr);
81 if((x = (word & 0x000F)) != 0) {
82 cnt += fprintf(stdout, ",%s", g = grstr(x));
83 FREE(g);
84 }
85 disassemble_puts_code(cnt, pradr, 2, (WORD []){word, adr});
86}
87
88void disassemble_cmd_r(CMDTYPE cmdtype, const char *cmdname, WORD word, WORD pradr)
89{
90 char *g = NULL;
91 char *g1 = NULL;
92 char *g2 = NULL;
93 int cnt = 0;
94
95 cnt += fprintf(stdout, " %-7s ", cmdname);
96 if(cmdtype == R1_R2) {
97 g1 = grstr((word & 0x00F0) >> 4);
98 g2 = grstr(word & 0x000F);
99 cnt += fprintf(stdout, "%s,%s", g1, g2);
100 FREE(g1);
101 FREE(g2);
102 } else if(cmdtype == R_) {
103 g = grstr((word & 0x00F0) >> 4);
104 cnt += fprintf(stdout, "%s", g);
105 FREE(g);
106 }
107 disassemble_puts_code(cnt, pradr, 1, (WORD []){word});
108}
109
110void disassemble_dc(WORD word, WORD pradr)
111{
112 int cnt = 0;
113
114 cnt = fprintf(stdout, " DC %-5d ", word);
115 disassemble_puts_code(cnt, pradr, 1, (WORD []){word});
116 fprintf(stdout, " ::" );
117 print_dumpword(word, true);
118}
119
120void disassemble_ds(WORD wcnt, WORD pradr)
121{
122 int cnt = 0;
123
124 cnt = fprintf(stdout, " DS %-5d ", wcnt);
125 disassemble_puts_code(cnt, pradr, 1, (WORD []){0});
126 for(int i = 1; i < wcnt; i++) {
127 fprintf(stdout, "\n");
128 disassemble_puts_code(0, pradr+i, 1, (WORD []){0});
129 }
130}
131
132WORD zero_data_cnt(const WORD *data, WORD wordlen)
133{
134 WORD cnt = 0;
135 for(cnt = 0; cnt < wordlen && data[cnt] == 0; cnt++) {
136 ;
137 }
138 return cnt;
139}
140
141void disassemble_file(const char *file)
142{
143 WORD *buf = NULL;
144 WORD endptr = 0;
145 WORD w = 0;
146 FILE *fp = NULL;
147
148 assert(file != NULL);
149 if((fp = fopen(file, "rb")) == NULL) {
150 perror(file);
151 return;
152 }
153
154 buf = calloc_chk(MAX_MEMSIZE, sizeof(WORD), "disassemble_file");
155 while(fread(&w, sizeof(WORD), 1, fp) == 1) {
156 buf[endptr++] = w;
157 }
158 fclose(fp);
159 if (endptr == 0) {
160 fprintf(stderr, "%s: empty or unreadable file\n", file);
161 } else {
162 fprintf(stdout, "MAIN START\n");
163 disassemble_memory(buf, 0, endptr - 1);
164 fprintf(stdout, " END\n");
165 }
166 FREE(buf);
167}
168
169void disassemble_memory(WORD *memory, WORD start, WORD end)
170{
171 WORD cmd = 0;
172 CMDTYPE cmdtype = 0;
173 const char *cmdname = NULL;
174 bool inprogram = true;
175 WORD zcnt = 0;
176
177 WORD ptr = start;
178 while(ptr <= end) {
179 cmd = memory[ptr] & 0xFF00;
180 cmdname = getcmdname(cmd);
181 cmdtype = getcmdtype(cmd);
182 if((cmd > 0 && cmdname != NULL && code_gr_valid(memory[ptr]) == true) || (inprogram == true && memory[ptr] == 0)) {
183 if(cmdtype == R_ADR_X || cmdtype == ADR_X) {
184 disassemble_cmd_adr_x(cmdtype, cmdname, memory[ptr], memory[ptr + 1], ptr);
185 } else {
186 disassemble_cmd_r(cmdtype, cmdname, memory[ptr], ptr);
187 }
188 ptr += code2cmdwordlen(cmd);
189 inprogram = (cmd != 0x8100) ? true : false;
190 } else {
191 if(memory[ptr] == 0 && ((zcnt = zero_data_cnt(memory + ptr, end - ptr + 1)) > 1 || ptr == end)) { /* 0が2つ以上の場合とメモリー末尾の場合は、DSとみなす */
192 disassemble_ds(zcnt, ptr);
193 ptr += zcnt;
194 } else {
195 disassemble_dc(memory[ptr], ptr);
196 ptr++;
197 }
198 }
199 fprintf(stdout, "\n");
200 }
201}
#define FREE(ptr)
メモリを解放するマクロ
Definition cmem.h:22
void * calloc_chk(size_t nmemb, size_t size, const char *tag)
領域の数とサイズを指定してメモリーを確保するcallocを実行する
Definition cmem.c:34
void disassemble_puts_code(int ascol, WORD pradr, int wordc, WORD wordv[])
機械コードをコメントとして標準出力へ出力する
Definition disassemble.c:57
void disassemble_dc(WORD word, WORD pradr)
DCコマンドを逆アセンブルし、標準出力へ出力する
void disassemble_cmd_r(CMDTYPE cmdtype, const char *cmdname, WORD word, WORD pradr)
種類がR1_R2またはR_のコマンドを逆アセンブルし、標準出力へ出力する
Definition disassemble.c:88
int codecol
機械コードの出力列
Definition disassemble.c:6
void disassemble_file(const char *file)
CASL IIのオブジェクトファイルを逆アセンブルし、標準出力へ出力する
void disassemble_cmd_adr_x(CMDTYPE cmdtype, const char *cmdname, WORD word, WORD adr, WORD pradr)
種類がR_ADRまたはR_ADR_Xのコマンドを逆アセンブルし、標準出力へ出力する
Definition disassemble.c:69
void disassemble_ds(WORD wcnt, WORD pradr)
WORD zero_data_cnt(const WORD *data, WORD wordlen)
WORDデータから、値が0のWORDがいくつ連続するか返す
void disassemble_memory(WORD *memory, WORD start, WORD end)
メモリーを逆アセンブルし、標準出力へ出力する
WORD code2cmdwordlen(WORD code)
Definition struct.c:294
@ MAX_MEMSIZE
Definition struct.h:20
CMDTYPE getcmdtype(WORD code)
Definition struct.c:235
char * grstr(WORD word)
汎用レジスタの番号からレジスタを表す文字列を返す
Definition struct.c:312
CMDTYPE
Definition struct.h:73
@ R_
Definition struct.h:97
@ R_ADR_X
Definition struct.h:80
@ ADR_X
Definition struct.h:92
@ R1_R2
Definition struct.h:86
bool code_gr_valid(WORD code)
Definition struct.c:269
char * getcmdname(WORD code)
Definition struct.c:252
unsigned short WORD
16ビットの数値を表すデータ型
Definition word.h:9
void print_dumpword(WORD word, bool logicalmode)
WORD値を解析して表示する
Definition word.c:137