X-Git-Url: http://j8takagi.net/cgi-bin/gitweb.cgi?p=YACASL2.git;a=blobdiff_plain;f=src%2Fassemble.c;h=33fd93eb968fce26637180d452e3b688d8324662;hp=ee2ca63bc6dfa493d71f6e8a91ed2859e0b9ab9e;hb=8365c3016d2564c0498d2dc21300b1bff57e929b;hpb=1708c99d4b6263863304d48ebca3b3473d6a0112 diff --git a/src/assemble.c b/src/assemble.c index ee2ca63..33fd93e 100644 --- a/src/assemble.c +++ b/src/assemble.c @@ -1,12 +1,4 @@ -#include -#include -#include -#include -#include -#include - #include "assemble.h" -#include "cerr.h" /** * @brief ファイルストリームの現在行を番号付きで表示する @@ -34,7 +26,7 @@ void printline(FILE *stream, const char *filename, int lineno, char *line); WORD getadr(const char *prog, const char *str, PASS pass); /** - * @brief 汎用レジスタを表す文字列 からレジスタ番号を返す + * @brief 汎用レジスタを表す文字列からレジスタ番号を返す * * @brief 文字列が汎用レジスタを表さない場合は、0xFFFFを返す * @@ -45,7 +37,7 @@ WORD getadr(const char *prog, const char *str, PASS pass); * @param *str 汎用レジスタを表す文字列。「GR0」「GR1」・・・「GR7」のいずれか * @param is_x trueの場合は指標レジスタ */ -WORD getgr(const char *str, bool is_x); +WORD grword(const char *str, bool is_x); /** * @brief リテラルを返す @@ -238,7 +230,7 @@ void assemble_rpop(const CMDLINE *cmdl, PASS pass); * * @param *cmdtbl アセンブラ言語CASL IIの命令表 * @param *cmdl 1行分のラベル・コマンド・オペランド - * @param pass アセンブラが何回目かを表す数 + * @param pass アセンブルが何回目か */ bool casl2cmd(CMD *cmdtbl, const CMDLINE *cmdl, PASS pass); @@ -248,7 +240,7 @@ bool casl2cmd(CMD *cmdtbl, const CMDLINE *cmdl, PASS pass); * @return アセンブル成功時はtrue、失敗時はfalseを返す * * @param *cmdl 1行分のラベル・コマンド・オペランド - * @param pass アセンブラが何回目かを表す数 + * @param pass アセンブルが何回目か */ bool assemble_comet2cmd(const CMDLINE *cmdl, PASS pass); @@ -328,9 +320,9 @@ WORD getadr(const char *prog, const char *str, PASS pass) { WORD adr = 0x0; - if(*str == '=') { + if(str[0] == '=') { adr = getliteral(str, pass); - } else if(isdigit(*str) || *str == '-' || *str == '#') { + } else if(isdigit(str[0]) || str[0] == '-' || str[0] == '#') { adr = nh2word(str); } else { if(pass == SECOND) { @@ -342,17 +334,18 @@ WORD getadr(const char *prog, const char *str, PASS pass) return adr; } -WORD getgr(const char *str, bool is_x) +WORD grword(const char *str, bool is_x) { WORD r; /* "GR[0-7]" 以外の文字列では、0xFFFFを返して終了 */ - if(!(strlen(str) == 3 && strncmp(str, "GR", 2) == 0 && - (*(str+2) >= '0' && *(str+2) <= '0' + (GRSIZE - 1)))) + if(strlen(str) != 3 || + strncmp(str, "GR", 2) != 0 || + str[2] < '0' || str[2] > '0' + (GRSIZE - 1)) { return 0xFFFF; } - r = (WORD)(*(str+2) - '0'); + r = (WORD)(str[2] - '0'); /* GR0は指標レジスタとして用いることができない */ if(is_x == true && r == 0x0) { setcerr(120, ""); /* GR0 in operand x */ @@ -363,10 +356,11 @@ WORD getgr(const char *str, bool is_x) WORD getliteral(const char *str, PASS pass) { - assert(*str == '='); + assert(str[0] == '='); WORD adr = asptr->lptr; - if(*(++str) == '\'') { /* 文字定数 */ + str++; + if(str[0] == '\'') { /* 文字定数 */ writestr(str, true, pass); } else { writememory(nh2word(str), (asptr->lptr)++, pass); @@ -398,24 +392,28 @@ void writestr(const char *str, bool literal, PASS pass) for(; ;) { /* 閉じ「'」がないまま文字列が終了した場合 */ - if(*p == '\0') { + if(!p[0]) { setcerr(123, str); /* unclosed quote */ break; } /* 「'」の場合、次の文字が「'」でない場合は正常終了 */ - if(*p == '\'' && *(++p) != '\'') { - break; + if(p[0] == '\'') { + p++; + if(p[0] != '\'') { + break; + } } else if(literal == true && lw == true) { setcerr(124, str); /* more than one character in literal */ break; } /*リテラルの場合はリテラル領域に書込 */ if(literal == true) { - writememory(*(p++), (asptr->lptr)++, pass); + writememory(p[0], (asptr->lptr)++, pass); lw = true; } else { - writememory(*(p++), (asptr->ptr)++, pass); + writememory(p[0], (asptr->ptr)++, pass); } + p++; } } @@ -443,17 +441,15 @@ void assemble_start(const CMDLINE *cmdl, PASS pass) setcerr(106, ""); /* operand count mismatch */ return; } - if(*(cmdl->label) == '\0') { + if(!*(cmdl->label)) { setcerr(107, ""); /* no label in START */ return; } /* プログラム名の設定 */ strcpy(asptr->prog, cmdl->label); - /* オペランドがある場合、実行開始アドレスを設定 */ - if(pass == SECOND && cmdl->opd->opdv[0] != NULL) { - if((execptr->start = getlabel(asptr->prog, cmdl->opd->opdv[0])) == 0xFFFF) { - setcerr(103, cmdl->opd->opdv[0]); /* label not found */ - } + /* オペランドがある場合、書き込みと実行の開始アドレスを設定 */ + if(cmdl->opd->opdv[0] != NULL) { + asptr->ptr = execptr->start = getadr(asptr->prog, cmdl->opd->opdv[0], pass); } } @@ -471,7 +467,7 @@ void assemble_end(const CMDLINE *cmdl, PASS pass) else if(pass == SECOND) { execptr->end = asptr->lptr; } - *(asptr->prog) = '\0'; + strcpy(asptr->prog, ""); } void assemble_ds(const CMDLINE *cmdl, PASS pass) @@ -579,7 +575,7 @@ bool casl2cmd(CMD *cmdtbl, const CMDLINE *cmdl, PASS pass) { int i; void (*cmdptr)(); - for(i = 0; *(cmdtbl[i].name) != '\0'; i++) { + for(i = 0; *(cmdtbl[i].name); i++) { if(strcmp(cmdl->cmd, cmdtbl[i].name) == 0) { cmdptr = cmdtbl[i].ptr; (*cmdptr)(cmdl, pass); @@ -602,7 +598,7 @@ bool assemble_comet2cmd(const CMDLINE *cmdl, PASS pass) writememory(cmd, (asptr->ptr)++, pass); } /* 第1オペランドは汎用レジスタ */ - else if((r_r1 = getgr(cmdl->opd->opdv[0], false)) != 0xFFFF) { + else if((r_r1 = grword(cmdl->opd->opdv[0], false)) != 0xFFFF) { /* オペランド数1 */ if(cmdl->opd->opdc == 1) { if((cmd = getcmdcode(cmdl->cmd, R_)) == 0xFFFF) { @@ -613,7 +609,7 @@ bool assemble_comet2cmd(const CMDLINE *cmdl, PASS pass) writememory(cmd, (asptr->ptr)++, pass); } /* オペランド数2。第2オペランドは汎用レジスタ */ - else if(cmdl->opd->opdc == 2 && (x_r2 = getgr(cmdl->opd->opdv[1], false)) != 0xFFFF) { + else if(cmdl->opd->opdc == 2 && (x_r2 = grword(cmdl->opd->opdv[1], false)) != 0xFFFF) { if((cmd = getcmdcode(cmdl->cmd, R1_R2)) == 0xFFFF) { setcerr(109, cmdl->cmd); /* not command of operand "r1,r2" */ return false; @@ -631,7 +627,7 @@ bool assemble_comet2cmd(const CMDLINE *cmdl, PASS pass) cmd |= (r_r1 << 4); /* 第1オペランドは汎用レジスタ */ /* オペランド数3の場合 */ if(cmdl->opd->opdc == 3) { /* 第3オペランドは指標レジスタとして用いる汎用レジスタ */ - if((x_r2 = getgr(cmdl->opd->opdv[2], true)) == 0xFFFF) { + if((x_r2 = grword(cmdl->opd->opdv[2], true)) == 0xFFFF) { setcerr(125, cmdl->cmd); /* not GR in operand x */ return false; } @@ -654,7 +650,7 @@ bool assemble_comet2cmd(const CMDLINE *cmdl, PASS pass) } /* オペランド数2の場合 */ if(cmdl->opd->opdc == 2) { /* 第2オペランドは指標レジスタとして用いる汎用レジスタ */ - x_r2 = getgr(cmdl->opd->opdv[1], true); + x_r2 = grword(cmdl->opd->opdv[1], true); if(cerr->num > 0) { return false; } @@ -679,7 +675,7 @@ bool assemble_comet2cmd(const CMDLINE *cmdl, PASS pass) bool assembletok(const CMDLINE *cmdl, PASS pass) { /* 命令がない場合 */ - if(*(cmdl->cmd) == '\0') { + if(!*(cmdl->cmd)) { return true; } /* アセンブラ命令またはマクロ命令の書込 */ @@ -704,7 +700,7 @@ bool assembleline(const char *line, PASS pass) stat = (cerr->num == 0) ? true : false; if(cmdl != NULL) { if(stat == true) { - if(pass == FIRST && *(cmdl->label) != '\0') { + if(pass == FIRST && *(cmdl->label)) { stat = addlabel(asptr->prog, cmdl->label, asptr->ptr); } } @@ -757,6 +753,48 @@ bool assemblefile(const char *file, PASS pass) return (cerr->num == 0) ? true : false; } +void assemble(int filec, char *filev[], WORD adr) +{ + int i; + PASS pass; + WORD bp[filec]; + + asptr = malloc_chk(sizeof(ASPTR), "asptr"); /* アセンブル時のプロパティ用の領域確保 */ + asptr->prog = malloc_chk(LABELSIZE + 1, "asptr.prog"); + asptr->ptr = adr; + /* アセンブル。ラベル表作成のため、2回行う */ + for(pass = FIRST; pass <= SECOND; pass++) { + for(i = 0; i < filec; i++) { + /* データの格納開始位置 */ + if(pass == FIRST) { + bp[i] = asptr->ptr; + } else if(pass == SECOND) { + asptr->ptr = bp[i]; + } + if(execmode.trace == true || execmode.dump == true || + asmode.src == true || asmode.label == true || asmode.asdetail == true) + { + fprintf(stdout, "\nAssemble %s (%d)\n", filev[i], pass); + } + /* ファイルをアセンブル */ + if(assemblefile(filev[i], pass) == false) { + goto asfin; + } + } + if(pass == FIRST && asmode.label == true) { + fprintf(stdout, "\nLabel::::\n"); + printlabel(); + if(asmode.onlylabel == true) { + break; + } + } + } +asfin: + freelabel(); /* ラベルハッシュ表を解放 */ + FREE(asptr->prog); /* アセンブル時のプロパティを解放 */ + FREE(asptr); +} + /* assemble.hで定義された関数群 */ void addcerrlist_assemble() {