1962 lines
25 KiB
C
1962 lines
25 KiB
C
/* Unfinished assembler for Intel 8051. */
|
|
|
|
#include <stdio.h>
|
|
|
|
char buf[500];
|
|
int pass2;
|
|
unsigned int pc;
|
|
char *token;
|
|
int token_flag;
|
|
char *syntax = "syntax error";
|
|
FILE *fo, *fl;
|
|
int nsym;
|
|
int nline;
|
|
|
|
typedef struct {
|
|
char s[34];
|
|
int v, type;
|
|
} SYMBOL;
|
|
|
|
SYMBOL *sym[10000];
|
|
|
|
main(argc, argv)
|
|
int argc;
|
|
char *argv[];
|
|
{
|
|
FILE *f;
|
|
|
|
if (argc != 2) {
|
|
printf("usage: asm51 filename\n");
|
|
exit();
|
|
}
|
|
|
|
pass(argv[1]);
|
|
|
|
pass2 = 1;
|
|
|
|
fo = fopen("object", "w");
|
|
|
|
fl = fopen("listing", "w");
|
|
|
|
pass(argv[1]);
|
|
|
|
dump_symbol_table();
|
|
}
|
|
|
|
pass(s)
|
|
char *s;
|
|
{
|
|
FILE *f;
|
|
|
|
pc = 0;
|
|
|
|
nline = 1;
|
|
|
|
f = fopen(s, "r");
|
|
|
|
while (fgets(buf, 500, f)) {
|
|
nline++;
|
|
parse();
|
|
}
|
|
|
|
fclose(f);
|
|
}
|
|
|
|
#define ACALL 0
|
|
#define ADD 1
|
|
#define ADDC 2
|
|
#define AJMP 3
|
|
#define ANL 4
|
|
#define CJNE 5
|
|
#define CLR 6
|
|
#define CPL 7
|
|
#define DA 8
|
|
#define DEC 9
|
|
#define DIV 10
|
|
#define DJNZ 11
|
|
#define INC 12
|
|
#define JB 13
|
|
#define JBC 14
|
|
#define JC 15
|
|
#define JMP 16
|
|
#define JNB 17
|
|
#define JNC 18
|
|
#define JNZ 19
|
|
#define JZ 20
|
|
#define LCALL 21
|
|
#define LJMP 22
|
|
#define MOV 23
|
|
#define MOVC 24
|
|
#define MOVX 25
|
|
#define MUL 26
|
|
#define NOP 27
|
|
#define ORL 28
|
|
#define POP 29
|
|
#define PUSH 30
|
|
#define RET 31
|
|
#define RETI 32
|
|
#define RL 33
|
|
#define RLC 34
|
|
#define RR 35
|
|
#define RRC 36
|
|
#define SETB 37
|
|
#define SJMP 38
|
|
#define SUBB 39
|
|
#define SWAP 40
|
|
#define XCH 41
|
|
#define XCHD 42
|
|
#define XRL 43
|
|
|
|
char *s, tokenstr[500], labelstr[500];
|
|
|
|
parse()
|
|
{
|
|
s = buf;
|
|
|
|
token_flag = 0;
|
|
|
|
label();
|
|
|
|
opcode();
|
|
}
|
|
|
|
label()
|
|
{
|
|
if (istoken(*s)) {
|
|
gettoken();
|
|
strcpy(labelstr, tokenstr);
|
|
gettoken();
|
|
if (strcmp(tokenstr, ":") != 0)
|
|
ungettoken();
|
|
} else
|
|
*labelstr = 0;
|
|
}
|
|
|
|
ungettoken()
|
|
{
|
|
token_flag = 1;
|
|
}
|
|
|
|
gettoken()
|
|
{
|
|
int i;
|
|
char *t = tokenstr;
|
|
|
|
if (token_flag) {
|
|
token_flag = 0;
|
|
return;
|
|
}
|
|
|
|
while (*s == ' ' || *s == '\t')
|
|
s++;
|
|
|
|
token = s;
|
|
|
|
if (*s == 0 || *s == '\n' || *s == '\r' || *s == ';') {
|
|
*t = 0;
|
|
return;
|
|
}
|
|
|
|
if (istoken(*s))
|
|
while (istoken(*s))
|
|
*t++ = *s++;
|
|
else
|
|
*t++ = *s++;
|
|
|
|
*t = 0;
|
|
}
|
|
|
|
istoken(c)
|
|
int c;
|
|
{
|
|
return c >= '0' && c <= '9' || c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z' || c == '_';
|
|
}
|
|
|
|
char *ops[44] = {
|
|
"ACALL",
|
|
"ADD",
|
|
"ADDC",
|
|
"AJMP",
|
|
"ANL",
|
|
"CJNE",
|
|
"CLR",
|
|
"CPL",
|
|
"DA",
|
|
"DEC",
|
|
"DIV",
|
|
"DJNZ",
|
|
"INC",
|
|
"JB",
|
|
"JBC",
|
|
"JC",
|
|
"JMP",
|
|
"JNB",
|
|
"JNC",
|
|
"JNZ",
|
|
"JZ",
|
|
"LCALL",
|
|
"LJMP",
|
|
"MOV",
|
|
"MOVC",
|
|
"MOVX",
|
|
"MUL",
|
|
"NOP",
|
|
"ORL",
|
|
"POP",
|
|
"PUSH",
|
|
"RET",
|
|
"RETI",
|
|
"RL",
|
|
"RLC",
|
|
"RR",
|
|
"RRC",
|
|
"SETB",
|
|
"SJMP",
|
|
"SUBB",
|
|
"SWAP",
|
|
"XCH",
|
|
"XCHD",
|
|
"XRL",
|
|
};
|
|
|
|
findopcode(s)
|
|
char *s;
|
|
{
|
|
int l = 0, m, u = 43, x;
|
|
for (;;) {
|
|
m = (l + u) / 2;
|
|
x = strcmp(s, ops[m]);
|
|
if (x == 0)
|
|
return m;
|
|
if (x < 0)
|
|
u = m - 1;
|
|
if (x > 0)
|
|
l = m + 1;
|
|
if (l > u)
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
opcode()
|
|
{
|
|
gettoken();
|
|
|
|
if (*tokenstr == 0) {
|
|
definelabel();
|
|
return;
|
|
}
|
|
|
|
switch (findopcode(tokenstr)) {
|
|
|
|
case ACALL:
|
|
definelabel();
|
|
acall();
|
|
break;
|
|
|
|
case ADD:
|
|
definelabel();
|
|
add();
|
|
break;
|
|
|
|
case ADDC:
|
|
definelabel();
|
|
addc();
|
|
break;
|
|
|
|
case AJMP:
|
|
definelabel();
|
|
ajmp();
|
|
break;
|
|
|
|
case ANL:
|
|
definelabel();
|
|
anl();
|
|
break;
|
|
|
|
case CJNE:
|
|
definelabel();
|
|
cjne();
|
|
break;
|
|
|
|
case CLR:
|
|
definelabel();
|
|
clr();
|
|
break;
|
|
|
|
case CPL:
|
|
definelabel();
|
|
cpl();
|
|
break;
|
|
|
|
case DA:
|
|
definelabel();
|
|
da();
|
|
break;
|
|
|
|
case DEC:
|
|
definelabel();
|
|
dec();
|
|
break;
|
|
|
|
case DIV:
|
|
definelabel();
|
|
div();
|
|
break;
|
|
|
|
case DJNZ:
|
|
definelabel();
|
|
djnz();
|
|
break;
|
|
|
|
case INC:
|
|
definelabel();
|
|
inc();
|
|
break;
|
|
|
|
case JB:
|
|
definelabel();
|
|
jb();
|
|
break;
|
|
|
|
case JBC:
|
|
definelabel();
|
|
jbc();
|
|
break;
|
|
|
|
case JC:
|
|
definelabel();
|
|
jc();
|
|
break;
|
|
|
|
case JMP:
|
|
definelabel();
|
|
jmp();
|
|
break;
|
|
|
|
case JNB:
|
|
definelabel();
|
|
jnb();
|
|
break;
|
|
|
|
case JNC:
|
|
definelabel();
|
|
jnc();
|
|
break;
|
|
|
|
case JNZ:
|
|
definelabel();
|
|
jnz();
|
|
break;
|
|
|
|
case JZ:
|
|
definelabel();
|
|
jz();
|
|
break;
|
|
|
|
case LCALL:
|
|
definelabel();
|
|
lcall();
|
|
break;
|
|
|
|
case LJMP:
|
|
definelabel();
|
|
ljmp();
|
|
break;
|
|
|
|
case MOV:
|
|
definelabel();
|
|
mov();
|
|
break;
|
|
|
|
case MOVC:
|
|
definelabel();
|
|
movc();
|
|
break;
|
|
|
|
case MOVX:
|
|
definelabel();
|
|
movx();
|
|
break;
|
|
|
|
case NOP:
|
|
definelabel();
|
|
nop();
|
|
break;
|
|
|
|
case MUL:
|
|
definelabel();
|
|
mul();
|
|
break;
|
|
|
|
case ORL:
|
|
definelabel();
|
|
orl();
|
|
break;
|
|
|
|
case POP:
|
|
definelabel();
|
|
pop();
|
|
break;
|
|
|
|
case PUSH:
|
|
definelabel();
|
|
push();
|
|
break;
|
|
|
|
case RET:
|
|
definelabel();
|
|
ret();
|
|
break;
|
|
|
|
case RETI:
|
|
definelabel();
|
|
reti();
|
|
break;
|
|
|
|
case RL:
|
|
definelabel();
|
|
rl();
|
|
break;
|
|
|
|
case RLC:
|
|
definelabel();
|
|
rlc();
|
|
break;
|
|
|
|
case RR:
|
|
definelabel();
|
|
rr();
|
|
break;
|
|
|
|
case RRC:
|
|
definelabel();
|
|
rrc();
|
|
break;
|
|
|
|
case SETB:
|
|
definelabel();
|
|
setb();
|
|
break;
|
|
|
|
case SJMP:
|
|
definelabel();
|
|
sjmp();
|
|
break;
|
|
|
|
case SUBB:
|
|
definelabel();
|
|
subb();
|
|
break;
|
|
|
|
case SWAP:
|
|
definelabel();
|
|
swap();
|
|
break;
|
|
|
|
case XCH:
|
|
definelabel();
|
|
xch();
|
|
break;
|
|
|
|
case XCHD:
|
|
definelabel();
|
|
xchd();
|
|
break;
|
|
|
|
case XRL:
|
|
definelabel();
|
|
xrl();
|
|
break;
|
|
|
|
default:
|
|
error("bad opcode");
|
|
break;
|
|
}
|
|
}
|
|
|
|
#define ACCUMULATOR 0
|
|
#define DIRECT 1
|
|
#define INDIRECT 2
|
|
#define REGISTER 3
|
|
#define IMMEDIATE 4
|
|
#define CARRY 5
|
|
#define DPTR 6
|
|
#define NOTBIT 7
|
|
#define AT_DPTR 8
|
|
|
|
acall()
|
|
{
|
|
unsigned int addr;
|
|
|
|
if (operand(&addr) != DIRECT)
|
|
error(syntax);
|
|
|
|
if (pass2 && (addr & 0xf800) != ((pc + 2) & 0xf800))
|
|
error(syntax);
|
|
|
|
emit_2(addr >> 3 & 0xe0 | 0x11, addr & 0xff); /* ACALL addr11 */
|
|
}
|
|
|
|
add()
|
|
{
|
|
unsigned int d, dst, s, src;
|
|
|
|
d = operand(&dst);
|
|
|
|
comma();
|
|
|
|
s = operand(&src);
|
|
|
|
if (d == ACCUMULATOR && s == REGISTER)
|
|
emit_1(0x28 | src); /* ADD A,Rn */
|
|
|
|
else if (d == ACCUMULATOR && s == DIRECT)
|
|
emit_2(0x25, src); /* ADD A,direct */
|
|
|
|
else if (d == ACCUMULATOR && s == INDIRECT)
|
|
emit_1(0x26 | src); /* ADD A,@Ri */
|
|
|
|
else if (d == ACCUMULATOR && s == IMMEDIATE)
|
|
emit_2(0x24, src); /* ADD A,#data */
|
|
|
|
else
|
|
error(syntax);
|
|
}
|
|
|
|
addc()
|
|
{
|
|
unsigned int d, dst, s, src;
|
|
|
|
d = operand(&dst);
|
|
|
|
comma();
|
|
|
|
s = operand(&src);
|
|
|
|
if (d == ACCUMULATOR && s == REGISTER)
|
|
emit_1(0x38 | src); /* ADDC A,Rn */
|
|
|
|
else if (d == ACCUMULATOR && s == DIRECT)
|
|
emit_2(0x35, src); /* ADDC A,direct */
|
|
|
|
else if (d == ACCUMULATOR && s == INDIRECT)
|
|
emit_1(0x36 | src); /* ADDC A,@Ri */
|
|
|
|
else if (d == ACCUMULATOR && s == IMMEDIATE)
|
|
emit_2(0x34, src); /* ADDC A,#data */
|
|
|
|
else
|
|
error(syntax);
|
|
}
|
|
|
|
ajmp()
|
|
{
|
|
unsigned int addr;
|
|
|
|
if (operand(&addr) != DIRECT)
|
|
error(syntax);
|
|
|
|
if (pass2 && (addr & 0xf800) != ((pc + 2) & 0xf800))
|
|
error(syntax);
|
|
|
|
emit_2(addr >> 3 & 0xe0 | 0x01, addr & 0xff); /* AJMP addr11 */
|
|
}
|
|
|
|
anl()
|
|
{
|
|
unsigned int d, dst, s, src;
|
|
|
|
d = operand(&dst);
|
|
|
|
comma();
|
|
|
|
s = operand(&src);
|
|
|
|
if (d == ACCUMULATOR && s == REGISTER)
|
|
emit_1(0x58 | src); /* ANL A,Rn */
|
|
|
|
else if (d == ACCUMULATOR && s == DIRECT)
|
|
emit_2(0x55, src); /* ANL A,direct */
|
|
|
|
else if (d == ACCUMULATOR && s == INDIRECT)
|
|
emit_1(0x56 | src); /* ANL A,@Ri */
|
|
|
|
else if (d == ACCUMULATOR && s == IMMEDIATE)
|
|
emit_1(0x54, src); /* ANL A,#data */
|
|
|
|
else if (d == DIRECT && s == ACCUMULATOR)
|
|
emit_2(0x52, dst); /* ANL direct,A */
|
|
|
|
else if (d == DIRECT && s == IMMEDIATE)
|
|
emit_3(0x53, dst, src); /* ANL direct,#data */
|
|
|
|
else if (d == CARRY && s == DIRECT)
|
|
emit_2(0x82, src); /* ANL C,bit */
|
|
|
|
else if (d == CARRY && s == NOTBIT)
|
|
emit_2(0xb0, src); /* ANL C,/bit */
|
|
|
|
else
|
|
error(syntax);
|
|
}
|
|
|
|
cjne()
|
|
{
|
|
unsigned int addr, d, dst, s, src;
|
|
|
|
d = operand(&dst);
|
|
|
|
comma();
|
|
|
|
s = operand(&src);
|
|
|
|
comma();
|
|
|
|
if (operand(&addr) != DIRECT)
|
|
error(syntax);
|
|
|
|
if (d == ACCUMULATOR && s == DIRECT)
|
|
emit_3(0xb5, src, addr - pc - 3); /* CJNE A,direct,rel */
|
|
|
|
else if (d == ACCUMULATOR && s == IMMEDIATE)
|
|
emit_3(0xb4, src, addr - pc - 3); /* CJNE A,#data,rel */
|
|
|
|
else if (d == REGISTER && s == IMMEDIATE)
|
|
emit_3(0xb8 | dst, src, addr - pc - 3); /* CJNE Rn,#data,rel */
|
|
|
|
else if (d == INDIRECT && s == IMMEDIATE)
|
|
emit_3(0xb6 | dst, src, addr - pc - 3); /* CJNE @Ri,#data,rel */
|
|
|
|
else
|
|
error(syntax);
|
|
}
|
|
|
|
clr()
|
|
{
|
|
unsigned int d, dst;
|
|
|
|
d = operand(&dst);
|
|
|
|
if (d == ACCUMULATOR)
|
|
emit_1(0xf4); /* CLR A */
|
|
|
|
else if (d == CARRY)
|
|
emit_1(0xc3); /* CLR C */
|
|
|
|
else if (d == DIRECT)
|
|
emit_2(0xc2, dst); /* CLR bit */
|
|
|
|
else
|
|
error(syntax);
|
|
}
|
|
|
|
cpl()
|
|
{
|
|
unsigned int d, dst;
|
|
|
|
d = operand(&dst);
|
|
|
|
if (d == ACCUMULATOR)
|
|
emit_1(0xf4); /* CPL A */
|
|
|
|
else if (d == CARRY)
|
|
emit_1(0xb3); /* CPL C */
|
|
|
|
else if (d == DIRECT)
|
|
emit_2(0xb2, dst); /* CPL bit */
|
|
|
|
else
|
|
error(syntax);
|
|
}
|
|
|
|
da()
|
|
{
|
|
unsigned int d, dst;
|
|
|
|
d = operand(&dst);
|
|
|
|
if (d == ACCUMULATOR)
|
|
emit_1(0xd4); /* DA A */
|
|
|
|
else
|
|
error(syntax);
|
|
}
|
|
|
|
dec()
|
|
{
|
|
unsigned int d, dst;
|
|
|
|
d = operand(&dst);
|
|
|
|
if (d == ACCUMULATOR)
|
|
emit_1(0x14); /* DEC A */
|
|
|
|
else if (d == REGISTER)
|
|
emit_1(0x18 | dst); /* DEC Rn */
|
|
|
|
else if (d == DIRECT)
|
|
emit_2(0x15, dst); /* DEC direct */
|
|
|
|
else if (d == INDIRECT)
|
|
emit_1(0x16 | dst); /* DEC @Ri */
|
|
|
|
else
|
|
error(syntax);
|
|
}
|
|
|
|
div()
|
|
{
|
|
gettoken();
|
|
if (strcmp(tokenstr, "AB") != 0)
|
|
error(syntax);
|
|
|
|
emit_1(0x84); /* DIV AB */
|
|
}
|
|
|
|
djnz()
|
|
{
|
|
unsigned int addr, d, dst;
|
|
|
|
d = operand(&dst);
|
|
|
|
comma();
|
|
|
|
if (operand(&addr) != DIRECT)
|
|
error(syntax);
|
|
|
|
if (d == REGISTER)
|
|
emit_2(0xd8 | dst, addr - pc - 2); /* DJNZ Rn,rel */
|
|
|
|
else if (d == DIRECT)
|
|
emit_3(0xd5, dst, addr - pc - 3); /* DJNZ direct,rel */
|
|
|
|
else
|
|
error(syntax);
|
|
}
|
|
|
|
inc()
|
|
{
|
|
unsigned int d, dst;
|
|
|
|
d = operand(&dst);
|
|
|
|
if (d == ACCUMULATOR)
|
|
emit_1(0x04); /* INC A */
|
|
|
|
else if (d == REGISTER)
|
|
emit_1(0x08 | dst); /* INC Rn */
|
|
|
|
else if (d == DIRECT)
|
|
emit_2(0x05, dst); /* INC direct */
|
|
|
|
else if (d == INDIRECT)
|
|
emit_1(0x06 | dst); /* INC @Ri */
|
|
|
|
else if (d == DPTR)
|
|
emit_1(0xa3); /* INC DPTR */
|
|
|
|
else
|
|
error(syntax);
|
|
}
|
|
|
|
jb()
|
|
{
|
|
unsigned int bit, addr;
|
|
|
|
if (operand(&bit) != DIRECT)
|
|
error(syntax);
|
|
|
|
comma();
|
|
|
|
if (operand(&addr) != DIRECT)
|
|
error(syntax);
|
|
|
|
emit_3(0x20, bit, addr - pc - 3); /* JB bit,rel */
|
|
}
|
|
|
|
jbc()
|
|
{
|
|
unsigned int bit, addr;
|
|
|
|
if (operand(&bit) != DIRECT)
|
|
error(syntax);
|
|
|
|
comma();
|
|
|
|
if (operand(&addr) != DIRECT)
|
|
error(syntax);
|
|
|
|
emit_3(0x10, bit, addr - pc - 3); /* JBC bit,rel */
|
|
}
|
|
|
|
jc()
|
|
{
|
|
unsigned int addr;
|
|
|
|
if (operand(&addr) != DIRECT)
|
|
error(syntax);
|
|
|
|
emit_2(0x40, addr - pc - 2); /* JC rel */
|
|
}
|
|
|
|
jmp()
|
|
{
|
|
gettoken();
|
|
if (strcmp(tokenstr, "@") != 0)
|
|
error(syntax);
|
|
|
|
gettoken();
|
|
if (strcmp(tokenstr, "A") != 0)
|
|
error(syntax);
|
|
|
|
gettoken();
|
|
if (strcmp(tokenstr, "+") != 0)
|
|
error(syntax);
|
|
|
|
gettoken();
|
|
if (strcmp(tokenstr, "DPTR") != 0)
|
|
error(syntax);
|
|
|
|
emit_1(0x73); /* JMP @A+DPTR */
|
|
}
|
|
|
|
jnb()
|
|
{
|
|
unsigned int bit, addr;
|
|
|
|
if (operand(&bit) != DIRECT)
|
|
error(syntax);
|
|
|
|
comma();
|
|
|
|
if (operand(&addr) != DIRECT)
|
|
error(syntax);
|
|
|
|
emit_3(0x30, bit, addr - pc - 3); /* JNB bit,rel */
|
|
}
|
|
|
|
jnc()
|
|
{
|
|
unsigned int addr;
|
|
|
|
if (operand(&addr) != DIRECT)
|
|
error(syntax);
|
|
|
|
emit_2(0x50, addr - pc - 2); /* JNC rel */
|
|
}
|
|
|
|
jnz()
|
|
{
|
|
unsigned int addr;
|
|
|
|
if (operand(&addr) != DIRECT)
|
|
error(syntax);
|
|
|
|
emit_2(0x70, addr - pc - 2); /* JNZ rel */
|
|
}
|
|
|
|
jz()
|
|
{
|
|
unsigned int addr;
|
|
|
|
if (operand(&addr) != DIRECT)
|
|
error(syntax);
|
|
|
|
emit_2(0x60, addr - pc - 2); /* JZ rel */
|
|
}
|
|
|
|
lcall()
|
|
{
|
|
unsigned int addr;
|
|
|
|
if (operand(&addr) != DIRECT)
|
|
error(syntax);
|
|
|
|
emit_3(0x12, addr >> 8, addr & 0xff); /* LCALL addr16 */
|
|
}
|
|
|
|
ljmp()
|
|
{
|
|
unsigned int addr;
|
|
|
|
if (operand(&addr) != DIRECT)
|
|
error(syntax);
|
|
|
|
emit_3(0x02, addr >> 8, addr & 0xff); /* LJMP addr16 */
|
|
}
|
|
|
|
mov()
|
|
{
|
|
unsigned int d, dst, s, src;
|
|
|
|
d = operand(&dst);
|
|
|
|
comma();
|
|
|
|
s = operand(&src);
|
|
|
|
if (d == ACCUMULATOR && s == REGISTER)
|
|
emit_1(0xe8 | src); /* MOV A,Rn */
|
|
|
|
else if (d == ACCUMULATOR && s == DIRECT)
|
|
emit_2(0xe5, src); /* MOV A,direct */
|
|
|
|
else if (d == ACCUMULATOR && s == INDIRECT)
|
|
emit_1(0xe6 | src); /* MOV A,@Ri */
|
|
|
|
else if (d == ACCUMULATOR && s == IMMEDIATE)
|
|
emit_2(0x74, src); /* MOV A,#data */
|
|
|
|
else if (d == REGISTER && s == ACCUMULATOR)
|
|
emit_1(0xf8 | dst); /* MOV Rn,A */
|
|
|
|
else if (d == REGISTER && s == DIRECT)
|
|
emit_2(0xa8 | dst, src); /* MOV Rn,direct */
|
|
|
|
else if (d == REGISTER && s == IMMEDIATE)
|
|
emit_2(0x78 | dst, src); /* MOV Rn,#data */
|
|
|
|
else if (d == DIRECT && s == ACCUMULATOR)
|
|
emit_2(0xf5, dst); /* MOV direct,A */
|
|
|
|
else if (d == DIRECT && s == REGISTER)
|
|
emit_2(0x88 | src, dst); /* MOV direct,Rn */
|
|
|
|
else if (d == DIRECT && s == DIRECT)
|
|
emit_3(0x85, src, dst); /* MOV direct,direct */
|
|
|
|
else if (d == DIRECT && s == INDIRECT)
|
|
emit_2(0x86 | src, dst); /* MOV direct,@Ri */
|
|
|
|
else if (d == DIRECT && s == IMMEDIATE)
|
|
emit_3(0x75, dst, src); /* MOV direct,#data */
|
|
|
|
else if (d == INDIRECT && s == ACCUMULATOR)
|
|
emit_1(0xf6 | dst); /* MOV @Ri,A */
|
|
|
|
else if (d == INDIRECT && s == DIRECT)
|
|
emit_2(0xa6 | dst, src); /* MOV @Ri,direct */
|
|
|
|
else if (d == INDIRECT && s == IMMEDIATE)
|
|
emit_2(0x76 | dst, src); /* MOV @Ri,#data */
|
|
|
|
else if (d == CARRY && s == DIRECT)
|
|
emit_2(0xa2, src); /* MOV C,bit */
|
|
|
|
else if (d == DIRECT && s == CARRY)
|
|
emit_2(0x92, dst); /* MOV bit,C */
|
|
|
|
else if (d == DPTR && s == IMMEDIATE)
|
|
emit_3(0x90, src >> 8, src & 0xff); /* MOV DPTR,#data16 */
|
|
|
|
else
|
|
error(syntax);
|
|
}
|
|
|
|
movc()
|
|
{
|
|
gettoken();
|
|
if (strcmp(tokenstr, "A") != 0)
|
|
error(syntax);
|
|
|
|
comma();
|
|
|
|
gettoken();
|
|
if (strcmp(tokenstr, "@") != 0)
|
|
error(syntax);
|
|
|
|
gettoken();
|
|
if (strcmp(tokenstr, "A") != 0)
|
|
error(syntax);
|
|
|
|
gettoken();
|
|
if (strcmp(tokenstr, "+") != 0)
|
|
error(syntax);
|
|
|
|
gettoken();
|
|
|
|
if (strcmp(tokenstr, "DPTR") == 0)
|
|
emit_1(0x93); /* MOVC A,@A+DPTR */
|
|
|
|
else if (strcmp(tokenstr, "PC") == 0)
|
|
emit_1(0x83); /* MOVC A,@A+PC */
|
|
|
|
else
|
|
error(syntax);
|
|
}
|
|
|
|
movx()
|
|
{
|
|
unsigned int d, dst, s, src;
|
|
|
|
d = operand(&dst);
|
|
|
|
comma();
|
|
|
|
s = operand(&src);
|
|
|
|
if (d == ACCUMULATOR && s == INDIRECT)
|
|
emit_1(0xe2 | src); /* MOVX A,@Ri */
|
|
|
|
else if (d == ACCUMULATOR && s == AT_DPTR)
|
|
emit_1(0xe0); /* MOVX A,@DPTR */
|
|
|
|
else if (d == INDIRECT && s == ACCUMULATOR)
|
|
emit_1(0xf2 | dst); /* MOVX @Ri,A */
|
|
|
|
else if (d == AT_DPTR && s == ACCUMULATOR)
|
|
emit_1(0xf0); /* MOVX @DPTR,A */
|
|
|
|
else
|
|
error(syntax);
|
|
}
|
|
|
|
nop()
|
|
{
|
|
emit_1(0x00); /* NOP */
|
|
}
|
|
|
|
mul()
|
|
{
|
|
gettoken();
|
|
if (strcmp(tokenstr, "AB") != 0)
|
|
error(syntax);
|
|
|
|
emit_1(0xa4); /* MUL AB */
|
|
}
|
|
|
|
orl()
|
|
{
|
|
unsigned int d, dst, s, src;
|
|
|
|
d = operand(&dst);
|
|
|
|
comma();
|
|
|
|
s = operand(&src);
|
|
|
|
if (d == ACCUMULATOR && s == REGISTER)
|
|
emit_1(0x48 | src); /* ORL A,Rn */
|
|
|
|
else if (d == ACCUMULATOR && s == DIRECT)
|
|
emit_2(0x45, src); /* ORL A,direct */
|
|
|
|
else if (d == ACCUMULATOR && s == INDIRECT)
|
|
emit_1(0x46 | src); /* ORL A,@Ri */
|
|
|
|
else if (d == ACCUMULATOR && s == IMMEDIATE)
|
|
emit_1(0x44, src); /* ORL A,#data */
|
|
|
|
else if (d == DIRECT && s == ACCUMULATOR)
|
|
emit_2(0x42, dst); /* ORL direct,A */
|
|
|
|
else if (d == DIRECT && s == IMMEDIATE)
|
|
emit_3(0x43, dst, src); /* ORL direct,#data */
|
|
|
|
else if (d == CARRY && s == DIRECT)
|
|
emit_2(0x72, src); /* ORL C,bit */
|
|
|
|
else if (d == CARRY && s == NOTBIT)
|
|
emit_2(0xa0, src); /* ORL C,/bit */
|
|
|
|
else
|
|
error(syntax);
|
|
}
|
|
|
|
pop()
|
|
{
|
|
unsigned int d, dst;
|
|
|
|
if (operand(&dst) != DIRECT)
|
|
error(syntax);
|
|
|
|
emit_2(0xd0, dst); /* POP direct */
|
|
}
|
|
|
|
push()
|
|
{
|
|
unsigned int s, src;
|
|
|
|
if (operand(&src) != DIRECT)
|
|
error(syntax);
|
|
|
|
emit_2(0xc0, src); /* PUSH direct */
|
|
}
|
|
|
|
ret()
|
|
{
|
|
emit_1(0x22); /* RET */
|
|
}
|
|
|
|
reti()
|
|
{
|
|
emit_1(0x32); /* RETI */
|
|
}
|
|
|
|
rl()
|
|
{
|
|
unsigned int d, dst;
|
|
|
|
d = operand(&dst);
|
|
|
|
if (d == ACCUMULATOR)
|
|
emit_1(0x23); /* RL A */
|
|
|
|
else
|
|
error(syntax);
|
|
}
|
|
|
|
rlc()
|
|
{
|
|
unsigned int d, dst;
|
|
|
|
d = operand(&dst);
|
|
|
|
if (d == ACCUMULATOR)
|
|
emit_1(0x33); /* RLC A */
|
|
|
|
else
|
|
error(syntax);
|
|
}
|
|
|
|
rr()
|
|
{
|
|
unsigned int d, dst;
|
|
|
|
d = operand(&dst);
|
|
|
|
if (d == ACCUMULATOR)
|
|
emit_1(0x03); /* RR A */
|
|
|
|
else
|
|
error(syntax);
|
|
}
|
|
|
|
rrc()
|
|
{
|
|
unsigned int d, dst;
|
|
|
|
d = operand(&dst);
|
|
|
|
if (d == ACCUMULATOR)
|
|
emit_1(0x13); /* RRC A */
|
|
|
|
else
|
|
error(syntax);
|
|
}
|
|
|
|
setb()
|
|
{
|
|
unsigned int d, dst;
|
|
|
|
d = operand(&dst);
|
|
|
|
if (d == CARRY)
|
|
emit_1(0xd3); /* SETB C */
|
|
|
|
else if (d == DIRECT)
|
|
emit_2(0xd2, dst); /* SETB bit */
|
|
|
|
else
|
|
error(syntax);
|
|
}
|
|
|
|
sjmp()
|
|
{
|
|
unsigned int addr;
|
|
|
|
if (operand(&addr) != DIRECT)
|
|
error(syntax);
|
|
|
|
emit_2(0x80, addr - pc - 2); /* SJMP rel */
|
|
}
|
|
|
|
subb()
|
|
{
|
|
unsigned int d, dst, s, src;
|
|
|
|
d = operand(&dst);
|
|
|
|
comma();
|
|
|
|
s = operand(&src);
|
|
|
|
if (d == ACCUMULATOR && s == REGISTER)
|
|
emit_1(0x98 | src); /* SUBB A,Rn */
|
|
|
|
else if (d == ACCUMULATOR && s == DIRECT)
|
|
emit_2(0x95, src); /* SUBB A,direct */
|
|
|
|
else if (d == ACCUMULATOR && s == INDIRECT)
|
|
emit_1(0x96 | src); /* SUBB A,@Ri */
|
|
|
|
else if (d == ACCUMULATOR && s == IMMEDIATE)
|
|
emit_2(0x94, src); /* SUBB A,#data */
|
|
|
|
else
|
|
error(syntax);
|
|
}
|
|
|
|
swap()
|
|
{
|
|
unsigned int d, dst;
|
|
|
|
d = operand(&dst);
|
|
|
|
if (d == ACCUMULATOR)
|
|
emit_1(0xc4); /* SWAP A */
|
|
|
|
else
|
|
error(syntax);
|
|
}
|
|
|
|
xch()
|
|
{
|
|
unsigned int d, dst, s, src;
|
|
|
|
d = operand(&dst);
|
|
|
|
comma();
|
|
|
|
s = operand(&src);
|
|
|
|
if (d == ACCUMULATOR && s == REGISTER)
|
|
emit_1(0xc8 | src); /* XCH A,Rn */
|
|
|
|
else if (d == ACCUMULATOR && s == DIRECT)
|
|
emit_2(0xc5, src); /* XCH A,direct */
|
|
|
|
else if (d == ACCUMULATOR && s == INDIRECT)
|
|
emit_1(0xc6 | src); /* XCH A,@Ri */
|
|
|
|
else
|
|
error(syntax);
|
|
}
|
|
|
|
xchd()
|
|
{
|
|
unsigned int d, dst, s, src;
|
|
|
|
d = operand(&dst);
|
|
|
|
comma();
|
|
|
|
s = operand(&src);
|
|
|
|
if (d == ACCUMULATOR && s == INDIRECT)
|
|
emit_1(0xd6 | src); /* XCHD A,@Ri */
|
|
|
|
else
|
|
error(syntax);
|
|
}
|
|
|
|
xrl()
|
|
{
|
|
unsigned int d, dst, s, src;
|
|
|
|
d = operand(&dst);
|
|
|
|
comma();
|
|
|
|
s = operand(&src);
|
|
|
|
if (d == ACCUMULATOR && s == REGISTER)
|
|
emit_1(0x68 | src); /* XRL A,Rn */
|
|
|
|
else if (d == ACCUMULATOR && s == DIRECT)
|
|
emit_2(0x65, src); /* XRL A,direct */
|
|
|
|
else if (d == ACCUMULATOR && s == INDIRECT)
|
|
emit_1(0x66 | src); /* XRL A,@Ri */
|
|
|
|
else if (d == ACCUMULATOR && s == IMMEDIATE)
|
|
emit_1(0x64, src); /* XRL A,#data */
|
|
|
|
else if (d == DIRECT && s == ACCUMULATOR)
|
|
emit_2(0x62, dst); /* XRL direct,A */
|
|
|
|
else if (d == DIRECT && s == IMMEDIATE)
|
|
emit_3(0x63, dst, src); /* XRL direct,#data */
|
|
|
|
else
|
|
error(syntax);
|
|
}
|
|
|
|
operand(x)
|
|
int *x;
|
|
{
|
|
gettoken();
|
|
|
|
if (strcmp(tokenstr, "A") == 0)
|
|
return ACCUMULATOR;
|
|
|
|
if (strcmp(tokenstr, "C") == 0)
|
|
return CARRY;
|
|
|
|
if (strcmp(tokenstr, "/") == 0) {
|
|
*x = expr();
|
|
return NOTBIT;
|
|
}
|
|
|
|
if (strcmp(tokenstr, "DPTR") == 0)
|
|
return DPTR;
|
|
|
|
if (*tokenstr == '#') {
|
|
*x = expr();
|
|
return IMMEDIATE;
|
|
}
|
|
|
|
if (*tokenstr == '@') {
|
|
gettoken();
|
|
if (strcmp(tokenstr, "R0") == 0) {
|
|
*x = 0x00;
|
|
return INDIRECT;
|
|
}
|
|
if (strcmp(tokenstr, "R1") == 0) {
|
|
*x = 0x01;
|
|
return INDIRECT;
|
|
}
|
|
if (strcmp(tokenstr, "DPTR") == 0)
|
|
return AT_DPTR;
|
|
error(syntax);
|
|
}
|
|
|
|
if (strcmp(tokenstr, "R0") == 0) {
|
|
*x = 0x00;
|
|
return REGISTER;
|
|
}
|
|
|
|
if (strcmp(tokenstr, "R1") == 0) {
|
|
*x = 0x01;
|
|
return REGISTER;
|
|
}
|
|
|
|
if (strcmp(tokenstr, "R2") == 0) {
|
|
*x = 0x02;
|
|
return REGISTER;
|
|
}
|
|
|
|
if (strcmp(tokenstr, "R3") == 0) {
|
|
*x = 0x03;
|
|
return REGISTER;
|
|
}
|
|
|
|
if (strcmp(tokenstr, "R4") == 0) {
|
|
*x = 0x04;
|
|
return REGISTER;
|
|
}
|
|
|
|
if (strcmp(tokenstr, "R5") == 0) {
|
|
*x = 0x05;
|
|
return REGISTER;
|
|
}
|
|
|
|
if (strcmp(tokenstr, "R6") == 0) {
|
|
*x = 0x06;
|
|
return REGISTER;
|
|
}
|
|
|
|
if (strcmp(tokenstr, "R7") == 0) {
|
|
*x = 0x07;
|
|
return REGISTER;
|
|
}
|
|
|
|
ungettoken();
|
|
|
|
*x = expr();
|
|
|
|
return DIRECT;
|
|
}
|
|
|
|
expr()
|
|
{
|
|
int v;
|
|
|
|
gettoken();
|
|
|
|
if (strcmp(tokenstr, "+") == 0)
|
|
v = term();
|
|
else if (strcmp(tokenstr, "-") == 0)
|
|
v = -term();
|
|
else {
|
|
ungettoken();
|
|
v = term();
|
|
}
|
|
|
|
for (;;) {
|
|
|
|
gettoken();
|
|
|
|
if (strcmp(tokenstr, "+") == 0)
|
|
v += term();
|
|
else if (strcmp(tokenstr, "-") == 0)
|
|
v -= term();
|
|
else {
|
|
ungettoken();
|
|
break;
|
|
}
|
|
}
|
|
|
|
return v;
|
|
}
|
|
|
|
term()
|
|
{
|
|
int v;
|
|
|
|
v = factor();
|
|
|
|
for (;;) {
|
|
|
|
gettoken();
|
|
|
|
if (strcmp(tokenstr, "*") == 0)
|
|
v *= factor();
|
|
else if (strcmp(tokenstr, "/") == 0)
|
|
v /= factor();
|
|
else {
|
|
ungettoken();
|
|
break;
|
|
}
|
|
}
|
|
|
|
return v;
|
|
}
|
|
|
|
factor()
|
|
{
|
|
gettoken();
|
|
|
|
if (strcmp(tokenstr, "$") == 0)
|
|
return pc;
|
|
|
|
else if (isdigit(*tokenstr))
|
|
return number();
|
|
|
|
else
|
|
error("bad factor");
|
|
}
|
|
|
|
number()
|
|
{
|
|
int c, u;
|
|
|
|
c = tokenstr[strlen(tokenstr) - 1];
|
|
|
|
if (c >= '0' && c <= '9')
|
|
u = decimal_number(0);
|
|
else
|
|
switch (c) {
|
|
|
|
case 'B':
|
|
u = binary_number();
|
|
break;
|
|
|
|
case 'D':
|
|
u = decimal_number(1);
|
|
break;
|
|
|
|
case 'H':
|
|
u = hex_number();
|
|
break;
|
|
|
|
case 'O':
|
|
case 'Q':
|
|
u = octal_number();
|
|
break;
|
|
|
|
default:
|
|
error("error in base designator");
|
|
break;
|
|
}
|
|
|
|
return u;
|
|
}
|
|
|
|
decimal_number(d)
|
|
int d;
|
|
{
|
|
int i, n;
|
|
char c;
|
|
unsigned long u = 0;
|
|
|
|
n = strlen(tokenstr) - d;
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
c = tokenstr[i];
|
|
|
|
if (c >= '0' && c <= '9')
|
|
u = 10 * u + c - '0';
|
|
else
|
|
error("error in decimal number");
|
|
|
|
if (u > 65535)
|
|
error("overflow in decimal number");
|
|
}
|
|
|
|
return (unsigned int) u;
|
|
}
|
|
|
|
binary_number()
|
|
{
|
|
int i, n;
|
|
char c;
|
|
unsigned long u = 0;
|
|
|
|
n = strlen(tokenstr) - 1;
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
c = tokenstr[i];
|
|
|
|
if (c >= '0' && c <= '1')
|
|
u = 2 * u + c - '0';
|
|
else
|
|
error("error in binary number");
|
|
|
|
if (u > 65535)
|
|
error("overflow in binary number");
|
|
}
|
|
|
|
return (unsigned int) u;
|
|
}
|
|
|
|
hex_number()
|
|
{
|
|
int i, n;
|
|
char c;
|
|
unsigned long u = 0;
|
|
|
|
n = strlen(tokenstr) - 1;
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
c = tokenstr[i];
|
|
|
|
if (c >= '0' && c <= '9')
|
|
u = 16 * u + c - '0';
|
|
else if (c >= 'A' && c <= 'Z')
|
|
u = 16 * u + c - 'A' + 10;
|
|
else
|
|
error("error in hex number");
|
|
|
|
if (u > 65535)
|
|
error("overflow in hex number");
|
|
}
|
|
|
|
return (unsigned int) u;
|
|
}
|
|
|
|
octal_number()
|
|
{
|
|
int i, n;
|
|
char c;
|
|
unsigned long u = 0;
|
|
|
|
n = strlen(tokenstr) - 1;
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
c = tokenstr[i];
|
|
|
|
if (c >= '0' && c <= '7')
|
|
u = 8 * u + c - '0';
|
|
else
|
|
error("error in octal number");
|
|
|
|
if (u > 65535)
|
|
error("overflow in octal number");
|
|
}
|
|
|
|
return (unsigned int) u;
|
|
}
|
|
|
|
comma()
|
|
{
|
|
gettoken();
|
|
if (strcmp(tokenstr, ",") != 0)
|
|
error("comma expected");
|
|
}
|
|
|
|
definelabel()
|
|
{
|
|
int i, l, m, u;
|
|
|
|
if (*labelstr == 0 || pass2)
|
|
return;
|
|
|
|
l = 0;
|
|
|
|
u = nsym - 1;
|
|
|
|
for (;;) {
|
|
|
|
if (l > u)
|
|
break;
|
|
|
|
m = (l + u) / 2;
|
|
|
|
i = strcmp(labelstr, sym[m]->s);
|
|
|
|
if (i < 0)
|
|
u = m - 1;
|
|
else if (i > 0)
|
|
l = m + 1;
|
|
else
|
|
error("label already defined");
|
|
}
|
|
|
|
if (nsym == 10000)
|
|
error("symbol table overflow");
|
|
|
|
for (i = nsym; i > l; i--)
|
|
sym[i] = sym[i - 1];
|
|
|
|
nsym++;
|
|
|
|
sym[l] = (SYMBOL *) malloc(sizeof (SYMBOL));
|
|
|
|
if (sym[l] == NULL)
|
|
error("out of memory");
|
|
|
|
strcpy(sym[l]->s, labelstr);
|
|
|
|
sym[l]->v = pc;
|
|
}
|
|
|
|
error(s)
|
|
char *s;
|
|
{
|
|
printf("%s", buf);
|
|
|
|
printf("line %d: %s\n", nline, s);
|
|
|
|
exit(0);
|
|
}
|
|
|
|
emit_1(x)
|
|
int x;
|
|
{
|
|
emit(x);
|
|
|
|
if (pass2)
|
|
fprintf(fl, "%04X %02X %s", pc, x, buf);
|
|
|
|
pc++;
|
|
}
|
|
|
|
emit_2(x, y)
|
|
int x, y;
|
|
{
|
|
emit(x);
|
|
emit(y);
|
|
|
|
if (pass2)
|
|
fprintf(fl, "%04X %02X %02X %s", pc, x, y, buf);
|
|
|
|
pc += 2;
|
|
}
|
|
|
|
emit_3(x, y, z)
|
|
int x, y, z;
|
|
{
|
|
emit(x);
|
|
emit(y);
|
|
emit(z);
|
|
|
|
if (pass2)
|
|
fprintf(fl, "%04X %02X %02X %02X %s", pc, x, y, z, buf);
|
|
|
|
pc += 3;
|
|
}
|
|
|
|
emit(i)
|
|
int i;
|
|
{
|
|
static int n;
|
|
if (pass2) {
|
|
if (i < -128 || i > 255)
|
|
error("operand out of range");
|
|
fprintf(fo, "%02X", i);
|
|
if (++n == 32) {
|
|
n = 0;
|
|
fprintf(fo, "\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
dump_symbol_table()
|
|
{
|
|
int i;
|
|
|
|
fprintf(fl, "symbol table\n");
|
|
|
|
for (i = 0; i < nsym; i++)
|
|
fprintf(fl, "%s %d\n", sym[i]->s, sym[i]->v);
|
|
}
|
|
|
|
/*
|
|
|
|
test file
|
|
|
|
MOV A,#10H
|
|
|
|
NOP
|
|
AJMP 0*256
|
|
LJMP 0
|
|
RR A
|
|
INC A
|
|
INC 0
|
|
INC @R0
|
|
INC @R1
|
|
INC R0
|
|
INC R1
|
|
INC R2
|
|
INC R3
|
|
INC R4
|
|
INC R5
|
|
INC R6
|
|
INC R7
|
|
JBC 0,$+3
|
|
ACALL 0*256
|
|
LCALL 0
|
|
RRC A
|
|
DEC A
|
|
DEC 0
|
|
DEC @R0
|
|
DEC @R1
|
|
DEC R0
|
|
DEC R1
|
|
DEC R2
|
|
DEC R3
|
|
DEC R4
|
|
DEC R5
|
|
DEC R6
|
|
DEC R7
|
|
JB 0,$+3
|
|
AJMP 1*256
|
|
RET
|
|
RL A
|
|
ADD A,#0
|
|
ADD A,0
|
|
ADD A,@R0
|
|
ADD A,@R1
|
|
ADD A,R0
|
|
ADD A,R1
|
|
ADD A,R2
|
|
ADD A,R3
|
|
ADD A,R4
|
|
ADD A,R5
|
|
ADD A,R6
|
|
ADD A,R7
|
|
JNB 0,$+3
|
|
ACALL 1*256
|
|
RETI
|
|
RLC A
|
|
ADDC A,#0
|
|
ADDC A,0
|
|
ADDC A,@R0
|
|
ADDC A,@R1
|
|
ADDC A,R0
|
|
ADDC A,R1
|
|
ADDC A,R2
|
|
ADDC A,R3
|
|
ADDC A,R4
|
|
ADDC A,R5
|
|
ADDC A,R6
|
|
ADDC A,R7
|
|
JC $+2
|
|
AJMP 2*256
|
|
ORL 0,A
|
|
ORL 0,#0
|
|
ORL A,#0
|
|
ORL A,0
|
|
ORL A,@R0
|
|
ORL A,@R1
|
|
ORL A,R0
|
|
ORL A,R1
|
|
ORL A,R2
|
|
ORL A,R3
|
|
ORL A,R4
|
|
ORL A,R5
|
|
ORL A,R6
|
|
ORL A,R7
|
|
JNC $+2
|
|
ACALL 2*256
|
|
ANL 0,A
|
|
ANL 0,#0
|
|
ANL A,#0
|
|
ANL A,0
|
|
ANL A,@R0
|
|
ANL A,@R1
|
|
ANL A,R0
|
|
ANL A,R1
|
|
ANL A,R2
|
|
ANL A,R3
|
|
ANL A,R4
|
|
ANL A,R5
|
|
ANL A,R6
|
|
ANL A,R7
|
|
JZ $+2
|
|
AJMP 3*256
|
|
XRL 0,A
|
|
XRL 0,#0
|
|
XRL A,#0
|
|
XRL A,0
|
|
XRL A,@R0
|
|
XRL A,@R1
|
|
XRL A,R0
|
|
XRL A,R1
|
|
XRL A,R2
|
|
XRL A,R3
|
|
XRL A,R4
|
|
XRL A,R5
|
|
XRL A,R6
|
|
XRL A,R7
|
|
JNZ $+2
|
|
ACALL 3*256
|
|
ORL C,0
|
|
JMP @A+DPTR
|
|
MOV A,#0
|
|
MOV 0,#0
|
|
MOV @R0,#0
|
|
MOV @R1,#0
|
|
MOV R0,#0
|
|
MOV R1,#0
|
|
MOV R2,#0
|
|
MOV R3,#0
|
|
MOV R4,#0
|
|
MOV R5,#0
|
|
MOV R6,#0
|
|
MOV R7,#0
|
|
SJMP $+2
|
|
AJMP 4*256
|
|
ANL C,0
|
|
MOVC A,@A+PC
|
|
DIV AB
|
|
MOV 0,0
|
|
MOV 0,@R0
|
|
MOV 0,@R1
|
|
MOV 0,R0
|
|
MOV 0,R1
|
|
MOV 0,R2
|
|
MOV 0,R3
|
|
MOV 0,R4
|
|
MOV 0,R5
|
|
MOV 0,R6
|
|
MOV 0,R7
|
|
MOV DPTR,#0
|
|
ACALL 4*256
|
|
MOV 0,C
|
|
MOVC A,@A+DPTR
|
|
SUBB A,#0
|
|
SUBB A,0
|
|
SUBB A,@R0
|
|
SUBB A,@R1
|
|
SUBB A,R0
|
|
SUBB A,R1
|
|
SUBB A,R2
|
|
SUBB A,R3
|
|
SUBB A,R4
|
|
SUBB A,R5
|
|
SUBB A,R6
|
|
SUBB A,R7
|
|
ORL C,/0
|
|
AJMP 5*256
|
|
MOV C,0
|
|
INC DPTR
|
|
MUL AB
|
|
|
|
MOV @R0,0
|
|
MOV @R1,0
|
|
MOV R0,0
|
|
MOV R1,0
|
|
MOV R2,0
|
|
MOV R3,0
|
|
MOV R4,0
|
|
MOV R5,0
|
|
MOV R6,0
|
|
MOV R7,0
|
|
ANL C,/0
|
|
ACALL 5*256
|
|
CPL 0
|
|
CPL C
|
|
CJNE A,#0,$+3
|
|
CJNE A,0,$+3
|
|
CJNE @R0,#0,$+3
|
|
CJNE @R1,#0,$+3
|
|
CJNE R0,#0,$+3
|
|
CJNE R1,#0,$+3
|
|
CJNE R2,#0,$+3
|
|
CJNE R3,#0,$+3
|
|
CJNE R4,#0,$+3
|
|
CJNE R5,#0,$+3
|
|
CJNE R6,#0,$+3
|
|
CJNE R7,#0,$+3
|
|
PUSH 0
|
|
AJMP 6*256
|
|
CLR 0
|
|
CLR C
|
|
SWAP A
|
|
XCH A,0
|
|
XCH A,@R0
|
|
XCH A,@R1
|
|
XCH A,R0
|
|
XCH A,R1
|
|
XCH A,R2
|
|
XCH A,R3
|
|
XCH A,R4
|
|
XCH A,R5
|
|
XCH A,R6
|
|
XCH A,R7
|
|
POP 0
|
|
ACALL 6*256
|
|
SETB 0
|
|
SETB C
|
|
DA A
|
|
DJNZ 0,$+3
|
|
XCHD A,@R0
|
|
XCHD A,@R1
|
|
DJNZ R0,$+2
|
|
DJNZ R1,$+2
|
|
DJNZ R2,$+2
|
|
DJNZ R3,$+2
|
|
DJNZ R4,$+2
|
|
DJNZ R5,$+2
|
|
DJNZ R6,$+2
|
|
DJNZ R7,$+2
|
|
MOVX A,@DPTR
|
|
AJMP 7*256
|
|
MOVX A,@R0
|
|
MOVX A,@R1
|
|
CLR A
|
|
MOV A,0
|
|
MOV A,@R0
|
|
MOV A,@R1
|
|
MOV A,R0
|
|
MOV A,R1
|
|
MOV A,R2
|
|
MOV A,R3
|
|
MOV A,R4
|
|
MOV A,R5
|
|
MOV A,R6
|
|
MOV A,R7
|
|
MOVX @DPTR,A
|
|
ACALL 7*256
|
|
MOVX @R0,A
|
|
MOVX @R1,A
|
|
CPL A
|
|
MOV 0,A
|
|
MOV @R0,A
|
|
MOV @R1,A
|
|
MOV R0,A
|
|
MOV R1,A
|
|
MOV R2,A
|
|
MOV R3,A
|
|
MOV R4,A
|
|
MOV R5,A
|
|
MOV R6,A
|
|
MOV R7,A
|
|
|
|
*/
|