指令系统
EM78156 & EM78P156 单片机共有的 58 条指令,其宽度为 13 位。(操作码+操作数)
指令周期
:取指令、分析指令、取操作数、执行
EM78 系列八位微控制器除一个指令需两个周期之外,其他的指令只需一个指令周期,除了对 PC (Program Counter)
做
“写”的指令,需二个指令周期,如 (MOV PC, A)。
EMC 汇编语言指令集
符号解说:
1.符号‘R’:代表寄存器中的一个。
2.符号‘B’:代表寄存器的某一位。
3.符号‘K’:代表 8 位或 10 位的常数。
4.符号‘A’:代表累加寄存器
5.常数之前加@
6.十六进制前加0x,十进制前不加
7.注释之前加;
8.ORG定义起始地址(伪指令)
9."=="
定义一代号值(PC == 0X02,需要在实际使用前定义)
1 ADD A,R ;A+R->A
2 ADD R,A ;A+R->R
3 AND A,R ;A&R->A
4 AND R,A ;A&R->R
5 CLR R ;0->R
6 CLRA ;0->A
7 COM R ;/R->R
8 COMA R ;/R->A
9 DAA ;A 寄存器调整为 BCD 值
10 DEC R ;R-1->R
11 DECA R ;R-1->A
12 DJZ R ;R-1->R 结果为零就跳过下一个指令
13 DJZA R ;R-1->A 结果为零就跳过下一个指令
14 INC R ;R+1->R
15 INCA R ;R+1->A
16 JZ R ;R+1->R, 结果为零就跳过下一个指令
17 JZA R ;R+1->A, 结果为零就跳过下一个指令
18 MOV R,A ;A->R
19 MOV A,R ;R->A
20 MOV R,R ;R->R
21 OR A,R ;A OR R ->A
22 OR R,A ;A OR R->R
23 SUB A,R ;R-A->A
24 SUB R,A ;R-A->R
25 XOR A,R ;A XOR R->A
26 XOR R,A ;A XOR R->R
27 BC R,B ;0->R(B)
28 BS R,B ;1->R(B)
29 JBC R,B ;如果 R(B)=0, 则跳过下一个指令
30 JBS R,B ;如果 R(B)=1, 则跳过下一个指令
31 RLC R ;循环左移
32 RLCA R ;循环左移 累加器A
33 RRC R ;循环右移
34 RRCA R ;循环右移A
35 SWAP R ;交换 R(0-3)->R(4-7) R(4-7)->R(0-3)
36 SWAPA R ;交换A 将所选定的寄存器﹐高 4 位以及低 4 位﹐互換
37 ;以下K为常量
38 ADD A,K ;A+K->A
39 AND A,K ;A&K->A
40 CALL K ;PC+1->[SP] ;(PAGE,K)->PC
41 CONTR ;CONT->A 读cont
42 CONTW ;A->CONT 写cont
43 DISI ;禁止中断
44 ENI ;使能中断
45 INT ;跳转到内存中的中断向量处 PC+1->[SP] 001H->PC
46 IOR R ;IOCR->A
47 IOW R ;A->IOCR 读写IO输入输出控制寄存器
48 JMP K ;(PAGE,K)->PC
49 MOV A,K ;K->A
50 NOP ;No Operation
51 OR A,K ;A OR K->A
52 RET ;[堆栈顶端]->PC ;return
53 RETI ;[堆栈顶端]->PC,使能中断 ;return 并开启中断
54 RETL K ;K->A, [堆栈顶端]->PC ;return 并返回值到A
55 SLEP ;0->WDT,振荡器停止振荡
56 SUB A,K ;K-A->A
57 TBL ;PC+A->PC 查找表 ;占用两个指令周期
58 WDTC ;0->WDT ; 清空看门狗计时器
59 XOR A,K ;A XOR K->A
寻址方式
立即数寻址(直接从指令中获取数据)
MOV A,@0x16 ;将常数0x16送给寄存器A
直接寻址(直接给出寄存器的地址)
;例:将寄存器 0X20 的内容,COPY 到寄存器 0X21 中。
MOV A, 0X20
MOV 0X21, A
间接寻址 (R4中存储的是另一个寄存器的地址)
R4 的 bit0-5 是用来选择寄存器(地址:00-06,0F-3F);方便循环寻址。
1 ;例:写一个程序,將寄存器 0X20~0X3F 的值都填 0。
2
3 MOV A, @0X20 ;设定A = 0X20。
4 MOV 0X04, A ;设定间接寻址寄存器(0X04)
5 AGAIN: ;的內含值为0X20
6 CLR 0 ;清除0X04所指的寄存器。
7 INC 0X04 ;递增间接寻址寄存器(0X04)
8 MOV A, 0X04 ;设定A=0X04寄存器的值。
9 XOR A, 0X3F ;比较间接寻址的位址是否
10 JBS 0X03, 2 ;以到0X3F。若是则结束。
11 JMP AGAIN ;否则在继续。
12 END:
位寻址
这种位寻址是对寄存器中的任一位(bit)进行操作。
BS 0x12,2 ;将寄存器0x12的第2位置为“1”。
例程(基本指令)
1.数据操作,(运算指令可以直接执行,数据在寄存器间的移动一定要以A为中转,立即数只能与A直接交互,数据拷贝到一般寄存器中只能通过A)
1 ;下两行指令敘述为 A = R11+ R12.
2 MOV A,0x11
3 ADD A,0x12 ;A = R11+ R12
1 ;下两行指令敘述为 R10= R11+ R12.
2 MOV A,0x11
3 MOV 0x10,A
4 MOV A,0x12
5 ADD 0x10,A ;R10= R11+ R12
1 ;下两行指令敘述为 A = 0x01 + 0x01.
2 MOV A,@0x01 ;A = 0x01
3 ADD A,@0x01 ;A = 0x02
1 ;將 port 6 和 R10register AND 起來, 并将结果输出到 port6
2 MOV A,0x6 ;從 port6 输入内容
3 AND A,0x10 ;把内容和 R10 做 AND
4 MOV 0x6,A ;将结果输出到 port6
1 R10= R11AND R12
2 MOV A,0x11
3 MOV 0x10,A
4 MOV A,0x12
5 AND 0x10,A ;R10= R11AND R12
1 ;R10 寄存器的位 “b”被清为 0。
2 MOV A,@0x0f
3 MOV 0x10,A ;R10= 00001111
4 BC 0x10,3 ;R10= 00000111
;將狀态寄存器的零标志設成 1。
BS 0x3,2
1 ;CALL k
2 ;操作內容 PC+1 --> [Top of Stack]
3 ; k --> PC(9::0)
4 ; R3(7::5) --> PC(12::10)
5 HERE:
6 CALL SUBRTN
7 CONT:
8 MOV A,@10
9
10 ;执行 CALL 指令之前
11 ;PC = address HERE
12 ;执行 CALL 指令之后
13 ;PC = address SUBRTN
14 ;[Top of Stack] = address CONT
CLR 0x10 ;清除 0x10 寄存器
CLRA ; 清除 A 寄存器﹐同時設定 Z 标志
1 ;COM R
2 ;将 R 暂存, 取补数(取反)﹐再存入 R 寄存器中。
3 MOV A,@0x11
4 MOV 0x10,A ;R10= 0x11
5 COM 0x10 ;R10= 0xEE
1 ;COMA R
2 ;将所指定的寄存器取补数﹐再放入 A 寄存器中。
3 ;从 port6 输入一个值﹐将其取补数之后在由 port6 输出。
4 MOV A,0x6
5 MOV 0x10,A
6 COMA 0x10
7 MOV 0x6,A
(减法运算,A中存放的是始终是减数!)
1 ;SUB A,R
2 ;將 R 寄存器中的值减去 A 寄存器中的值﹐再存回 A 寄存器中
3
4 ;SUB R,A
5 ;将 R 寄存器中的值减去 A 寄存器中的值﹐再存回 R 寄存器中。
6
7 ;SUB A, k
8 ;立即数 k 的值减去 A 寄存器中的值﹐再存回 A 寄存器中。
9
10 ;说明如何完成 A = 0x99-0x55 的计算式
11 MOV A,@0x99
12 MOV 0x10,A ;R10 = 0x99
13 MOV A,@0x55
14 SUB A,0x10 ;A = 0x44
15
16 ;说明如何完成 A = 0x02 - A 的计算式
17 MOV A,@0x01 ;A = 0x01
18 SUB A,@0x02 ;A = 0x02 - 0x01 = 0x01
19 ;C flag = 1 , 进位标志 C = 1﹐相减结果为正值。
1 ;IO配置
2 ;IOR R
3 ;将控制寄存器 IOCR中的值移到寄存器 A 中。
4 IOR 0xf ;取得 IOCF中的內容﹐并载入 A 中
5 MOV 0x10,A ;储存在寄存器 0x10 中
1 ;IOW R
2 ;将 A 寄存器(累加器)的内容载入控制寄存器 IOCR中
3 ;将 port6 設定成输出口。
4 MOV A, @0
5 IOW 0x6
循环:
1 ;DECA R
2 ;R-1 --> A
3 ;递减 R 寄存器的值﹐并且将结果存入 A 寄存器中。
4
5 ;说明如何作一个计数 16 次的循环
6 STATUS == 3 ﹔状态寄存器
7 Z_FLAG == 2 ﹔零标志在状态暂存中是 BIT2
8 MOV A,@0x10
9 MOV 0x10,A
10 LOOP:
11 DECA 0x10
12 MOV 0x10,A
13 JBS STATUS,Z_FLAG
14 JMP LOOP
1 ;DEC R
2 ;R-1 --> R
3 ;将所指定的 R 寄存器內含值减 1。
4
5 ;说明如何作一个计数 16 次的循环
6 STATUS == 3 ; 状态寄存器
7 Z_FLAG == 2 ﹔零标志在状态暂存中是 BIT2
8 MOV A,@0x10
9 MOV 0x10,A
10 LOOP:
11 DEC 0x10
12 JBS STATUS,Z_FLAG
13 JMP LOOP
1 ;DJZA R
2 ;R - 1 --> A, skip if 0
3 ;将所指定 R 寄存器的內含值减 1﹐并将结果存於 A 寄存器上﹔如果结果为
4 ;0﹐则下一个指令将被跳过。
5 ;举例说明
6
7 HERE:
8 DJZA 0x9
9 CONT:
10 MOV A,0x10
11 SKIP:
12 ADD A,@10
13
14 ;在执行 DJZA 指令之前
15 ;PC = address HERE
16 ;在执行 DJZA 指令之后
17 ;A=R9-1
18 ;if A = 0, PC = address SKIP
19 ;if A ≠0, PC = address CONT
1 ;DJZ R
2 ;R - 1 --> R, skip if 0
3 ;将所指定 R 寄存器的內含值减 1﹐并将结果存回 R 寄存器上﹔如果结果为
4 ;0﹐则下一个指令将被跳过。
5 ;寄存器 R10递减﹐ 若结果不等于
6 ;0 , 执行 JMP 指令﹐若結果等于 0﹐
7 ;JMP 指令不执行
8
9 MOV A,@100
10 MOV 0x10,A
11 LOOP:
12
13 DJZ 0x10
14 JMP LOOP
1 ;INCA R
2 ;R + 1 --> A
3 ;将被指定 R 寄存器的內含值加 1,并将结果储于 A 寄存器中。
4 MOV A,@0x11
5 MOV 0x10,A ;R10= 0x11
6 INCA 0x10 ;A = 0x12
7
8 ;INC R
9 ;R + 1 --> R
10 ;将被指定 R 寄存器的內含值加 1﹐並且将结果再存回 R 寄存器中。
11 MOV A,@0x11
12 MOV 0x10,A ;R10= 0x11
13 INC 0x10 ;R10= 0x12
跳转:(很多情况下,跳转伴随着++与--)
1 ;0x55﹐就跳到 ERROR 这支子程序。
2 STATUS == 3
3 Z_FLAG == 2
4 MOV A,@0x55
5 XOR A,0x10
6 JBS STATUS,Z_FLAG
7 JMP ERROR
1 ;JMP k
2 ;k --> PC(9::0)
3 ;R3(7::5) --> PC(12::10)
4 ;当执行一个跳转指令﹐指令后所描述的执行地址会载入程序计数器中。
5
6 HERE:
7 JMP BRANCH
8 ;执行 JMP 指令之前
9 ;PC = address HERE
10 ;执行 JMP 指令之后
11 ;PC = address BRANCH
1 ;JZA R
2 ;R+1 --> A, skip if result = 0
3 ;将所选定的寄存器 R 的內容加 1﹐并将结果存于 A 寄存器﹐若结果为 0﹐
4 ;则跳过下一个指令。
5 ;Port 6 输出递减的二进位数值。
6
7 MOV A,@0x00
8 LOOP:
9 MOV 0x6,A ;IO6
10 MOV 0x10,A
11 JZA 0x10
12 JMP LOOP
1 ;JZ R
2 ;R+1 --> R, skip if result = 0
3 ;将所选定的寄存器 R 的內容加 1﹐并将结果存於 R 寄存器﹐若结果为 0﹐
4 ;则跳过下一个指令。
5 HERE:
6 JZ 0x10
7 CONT:
8 MOV A,0x10
9 SKIP:
10 ADD A,@10
11 ;执行 JZ 指令之前
12 ;PC = address HERE
13 ;执行 JZ 指令之后
14 ;R10 = R10-1
15 ;if R10= 0, PC = address SKIP
16 ;if R10 ≠0, PC = address CONT
1 ;JBC R,b
2 ;if R(b) = 0, skip
3 ;如果寄存器 R 的位 “b”是“0”,则跳过下一个指令。
4 ;测试 0x10 寄存器的 bit0﹐若是为”0”则 port5 的 bit0 设成”0”﹔若
5 ;0x10 寄存器的 bit0 为”1”﹐則 port5 的 bit0 设成”1”。
6
7 JBC 0x10,0
8 BS 0x5,0
9 JBS 0x10,0
10 BC 0x5,0
1 ;JBS R,b
2 ;如果寄存器 R 的位 “b”是“1”,则跳过下一个指令。
3 ;
4 HERE JBC 0x9,3
5 CONT MOV A,@10
6 SKIP ADD A,0x10
7 ;执行 JBC 指令之前
8 ;PC = address HERE
9 ;执行 JBC 指令之后
10 ;if R9(3) = 0, PC = address CONT
11 ;if R9(3) ≠0, PC = address SKIP
1 ;NOP
2 ;No Operation
3 ;不做任何工做﹐用来做时间的延迟。
4 ;
5 ;P50 输出 3 μs 的突波. (system clock = 2MHz)
6 BS 0x5,0x0 ;P50 输出为 high
7 NOP ;延迟两个指令周期
8 NOP
9 BC 0x5,0x0 ;P50 输出为 low
1 ;RET
2 ;[Top of Stack] --> PC
3 ;从子程序中返回, 堆栈最上面的数值载入程序计数器PC
4 ;
5 TEST:
6 ?
7 ?
8 RET
9 ?
10 ?
11 CALL TEST
12 HERE:
13 ADD A,@0x1
14 ?
15 ?
16 ;在呼叫 RET 指令之前。
17 ;堆栈的顶端 Top of Stack = address HERE
18 ;在呼叫 RET 指令之后。
19 ;程序计数器 PC = address HERE
1 ;RET L
2 ;RETL k
3 ;k --> A
4 ;[Top of Stack] --> PC
5 ;从子程序返回﹐并将立即值载入 A 寄存器(累加器)中。
6 ;堆栈最顶端的数值载入程序计数器中
7 ;建立一个 7 段显示器转換表﹐並用 port6 驱动 7 段显示器。
8
9 ;REGISTER DEFINE
10 PC == 2
11 TRANS:
12 ADD PC,A
13 RETL 0XFC
14 RETL 0XC0
15 RETL 0XEA
16 RETL 0XF2
17 RETL 0X66
18 RETL 0XB6
19 RETL 0XBE
20 RETL 0XE0
21 RETL 0XFE
22 RETL 0XF6
23 MAIN:
24 ?
25 ?
26 ?
27 MOV A,0x10 ;将寄存器的內含值载入 A 中
28 CALL TRANS
29 MOV 0x6,A ;输出到 7 段显示器
30 ?
31 ?
32 ?
中断
1 ;INT
2 ;PC + 1 --> [Top of Stack]
3 ;0001H --> PC
4
5 ;软件中断指令﹐首先将下一个地址存入堆栈中﹐然后将 0x01 载入程序寄
6 ;存器中。
7 ;执行 INT 指令之前
8 ;PC = address HERE
9 ;执行 INT 指令之后
10 ;PC = 0001H
11 ;[Top of Stack] = address CONT
12
13 ORG 0x001
14 JMP SET_INT
15
16 SET_INT﹕
17 。。。
18 RET
19
20 MAIN﹕
21 。。。
22
23 HERE﹕
24 INT
25 CONT﹕
26 CLRA
位操作:
移位操作(仅仅是循环移位,连同进位位一起,移位之前根据需要可能要先处理好进位位)
1 ;RLCA R
2 ;将所指定的寄存器的內容﹐连同进位标志一起向左移 1 位﹐并将结果存於
3 ;A 寄存器
4 ;将指定的寄存器放向左移 1 位﹐并将结果由 port6 输出。
5 BIT_BUF == 0x10
6 RLCA BIT_BUF
7 MOV 0x6,A
1 ;RLC
2 ;将所指定的寄存器的內容﹐连同进位标志向左移 1 个位原﹐结果存在原
3 ;先的寄存器。
4 RLCA 0x10 ﹔
5 RLC 0x10 ﹔將 0x10 寄存器的值向左移 1
6
1 ;RRCA R
2 ;R(n) --> A(n-1), R(0) --> C, C --> A(7)
3 ;R 寄存器的內含值又移 1-bit﹐右移时包含 C(进位标志) ﹐如下图﹐并将
4 ;结果存于 A 寄存器。
5 ;将指定的寄存器放向右移 1 位﹐并将结果由 port6 输出:
6 BIT_BUF == 0x10
7 RRCA BIT_BUF
8 MOV 0x6,A
1 ;RRC
2 ;R(n) --> R(n-1), R(0) --> C, C --> R(7)
3 ;所指定的寄存器的內容﹐连带着进位标志接向右移 1 位
4 MOV A,@0x0f
5 CLR 0x3,0 ;clear C flag
6 MOV 0x10,A ;R10= 00001111
7 RRC 0x10 ;R10= 00000111, C = 1
;SWAPA
;R(3::0) --> A(7::4)
;R(7::4) --> A(3::0)
;将所选定的寄存器﹐高 4 位以及低 4 位﹐互換﹐并将结果存于 A 寄存器。
;将 port6 的內容﹐高 4 位以及低 4 位互換。
MOV A,0x6
MOV 0x10,A
SWAP 0x10
MOV 0x6,A
1 ;SWAP
2 ;R(3::0) <--> R(7::4)
3 ;将所选定的寄存器﹐高 4 位以及低 4 位﹐互換。
4 MOV A,@0x43
5 MOV 0x10,A ;R10 = 0x43
6 SWAP 0x10 ;R10 = 0x34
逻辑操作:
1 ;XOR A,R
2 ;将A 寄存器的值和R 寄存器的值XOR 在一起﹐并且将结果存入A 寄存器中
3 ;XOR R,A
4 ;将A 寄存器的值和R 寄存器的值XOR 在一起﹐并且将结果存入R 寄存器中。
5 ;XOR A, k
6 ;
7 ;测试 0x10 寄存器內含值是否为 0x55﹐如果 0x10 寄存器的內含值不为
8 ;0x55﹐就跳到 ERROR 这支子程序。
9 STATUS == 3
10 Z_FLAG == 2
11 MOV A,@0x55
12 XOR A,0x10
13 JBS STATUS,Z_FLAG
14 JMP ERROR
15
16 ;下面的指令敘述﹐完成 R10= R11XOR R12
17 MOV A,0x11
18 MOV 0x10,A
19 MOV A,0x12
20 XOR 0x10,A ;R10= R11XOR R12
21
22 ;下面的指令敘述﹐完成 A = A XOR 0xF0.
23 MOV A,@0x00 ;A = 0x00
24 XOR A,@0xF0 ;A = 0xF0
时间: 2024-10-15 01:23:39