目录
一、指令的基础知识
1.1、指令的一般格式
汇编指令的一般格式为:[名字] 操作码 操作数1,操作数2,...;注释
[名字] :标号(指令所在地址的标志符号)或者是变量名;
操作码:可以类似得理解为C语言中的函数名,操作码比较正经的定义是操作的性质,在实际使用中和C语言中函数名类似,针对不同的操作用不同的操作码。
操作数:操作的对象,就是操作码要作用于谁。
注释:和其他语言一样。
1.2、指令分类
按所占字节分:
(1)单字节指令:操作码和操作数同在一个字节中。
(2)双字节指令:操作码占一个字节,操作数占一个字节。
(3)三字节指令:操作码占一个字节,操作数占两个字节。
按执行时间分(12T:一个机器周期为12个时钟震荡周期):
(1)1个机器周期指令
(2)2个机器周期指令
(3)4个机器周期指令,如乘除指令。
疑问:机器周期和时钟震荡周期具体是指什么?
二、指令系统的寻址方式
2.1、立即数寻址
在指令中直接写出来的操作数,就叫立即数,类似C语言中“a = 4”语句中,4就是立即数,直接写出来,不用寻找地址的数称为立即数。对于立即数,在使用时要在立即数前加“#”。
例如一个数据传输指令:
MOV A,#40H;40H -> A
这个指令就是将40H这个数值传给A。
注意:
(1)立即数只能做源操作数,不能做目的操作数。就是立即数只能赋值给其他操作数,而不能接受其他操作数传过来的数据。
(2)如果立即数以A~F开头的16进制数出现时,前面要再加个0。
疑问:加个0是加在数前还是#前?
2.2、寄存器寻址
指令中的操作数为寄存器的内容,例如R0~R7,A(不能是ACC),B,C,DPTR。
例如:
MOV A,R1; R1 -> A
疑问:(1)为什么不能是ACC?
(2)R0~R7,A,B,C都是什么寄存器?
2.3、直接寻址
在指令中直接写操作数的地址((40H)表示地址40H,的内容)
例如:
MOV A,40H;(40H)-> A
表示把地址40H的内容传给A。其中,两个操作数都可以由直接寻址给出,例如
MOV 40H,64H; (64H) -> 40H
直接寻址是访问片内特殊功能寄存器的唯一寻址方式。
在IAP15W4K58 单片机的片内基本RAM中,高128位和特殊功能寄存器的字节地址完全重合,但他们在物理上是完全独立的两个区域。对他们的寻址采用直接寻址和间接寻址来区别。直接寻址访问特殊功能寄存器,间接寻址访问高128位。就类似于两栋楼A和B,他们都有102这个编号的房间,但一个是在A楼的102,一个是在B楼的102,直接寻址就是去A楼的102,间接寻址就是去B楼的102。
2.4、寄存器间接寻址
当寄存器中存放的是操作数的地址,也就是先从寄存器中读取操作数的地址,在根据该地址去找操作数。这种操作体现在指令中,要在寄存器前加“@”,注意和寄存器寻址区分。
MOV A,@R0;若(R0) = 40H,即(40H) -> A
2.5、基址加变址寄存器间接寻址方式
该型号单片机中有PC有DPTR两个16位的寄存器,以DPTR和PC作为基址寄存器,以累加器A作为变址寄存器,两者相加就是源操作数的16位地址。
MOV A,@A+DPTR;若A = 05H,DPTR = 0400H,则(0405H) -> A
该指令不会改变DPTR的值,常常用于查表,DPTR作为表头,A作为偏移量,即表格的第一格开始后移A位,改变A的值就可以查表格中不同位置的内容。
2.6、相对寻址
PC的值加上偏移量rel,形成转移目的地址,用于使程序跳转(PC中存放的是下一条指令的地址)。例如
SJMP rel;(PC) + rel -> PC
偏移量rel是带符号的8位二进制数。PC本来包含的地址在加上rel偏移量得到的新地址再赋给PC,成为下一条执行指令的地址。
还有另一种SJMP,即将L00P地址直接赋给PC,成为下一条执行指令的地址。此时的偏移量rel由汇编程序自动计算。
SJMP L00P;
2.7、位寻址
对可寻址位 进行置1,置0,求反逻辑运算等操作。
MOV C,40H;
SETB IT0;
含义:(40H)-> C,然后对C寄存器中的IT0位单独操作。
三、数据传送指令
3.1、通用数据传送指令
MOV 目的操作数,源操作数;这个指令不会影响PSW中的CY,AC,OV标志位。
PSW:程序状态字寄存器,8位,分别是进位标志位Cy,可简写为C;A从,辅助进位标志位。F0,F1用户设定标志位,控制程序流向,RS1,RS0工作寄存器区选择。OV溢出标志位,P奇偶标志位。
3.2、堆栈操作指令
堆栈---内部RAM中的后进先出区域。 堆栈指针SP---指示堆栈的栈顶位置。
进栈:PUSH direct; 他的执行逻辑是:SP + 1 -> A, direct -> SP.先让指针指向下一个位置,然后把要存入的数据送给SP指向的位置。
出栈:POP direct。他的执行逻辑是:先将SP指向的内容送给direc,然后SP减一。
3.3、累加器A与外部数据存储器RAM/IO传送指令
读外部RAM/IO:MOVX A,@DPTR; MOVX A,@Ri
写外部RAM/IO:MOVX @DPTR,A; MOVX @Ri,A
DPTR是16位寄存器,可以对64KB的片外数据RAM寻址,高八位地址DPH由P2口输出,低八位地址DPL由P0口输出。
Ri可以对256B的片外数据寻址,8位地址由P0口输出。
3.4、查表指令
如上一章节所说的,查表一般用基址加变址寄存器间接寻址方式,把程序寄存器中的表格数据读到A中,就使用这种寻址方式。
MOVC A,@A+PC
他的优点是不用改变PC,只改变A就可以查询不同地址的数据,但A是八位的,这就意味着表格的数据只能存放在PC地址+256个单元内。
MOVC A,@A+DPTR
DPTR是16位寄存器,表格数据可以存放在+64KB个单元内,这个容量就大的多。
3.5、数据交换指令
字节交换指令:XCH A,Rn; 将A和Rn的内容互换。
半字节交换指令:XCHD A.@Ri A的低四位和Ri的低四位交换。
累加器半字节交换指令:SWAP A;累加器的低四位和高四位互换。
四、算数运算指令
4.1、加法指令
算数运算指令是针对八进制无符号二进制数的,会影响PSW的Cy,Ac,OV标志。
ADD A,#date; A + date -> A.
如果位7有进位,Cy = 1;如果位3有进位,Ac = 1;OV= 位6的进位 异或 位7的进位
4.2、带进位加法指令
ADDC A,#date;A + date + Cy -> A;
4.3、增1指令
INC A; 不会影响PSW中任何标志位。
4.4、十进制调整指令
两个压缩BCD码按二进制相加后,对A中的加法结果进行十进制调整,得到正确的压缩BCD码之和。
调整的准则:
(1)累加器低四位大于9或者辅助进位标志AC = 1,则加06H修正。
(2)累加器高四位大于9或者进位Cy = 1,则加60H修正。
4.5、带借位的减法指令
SUBB A,#date; A - date - Cy -> A
如果位7需借位,Cy=1;如果位3需借位,Ac=1;OV=位6的借位 异或 位7的借位
4.6、减1指令
DEC A; A - 1 -> A; 只影响奇偶标志位P;
4.7、无符号整数乘法指令
MUL AB; A * B = BA 结果的高位在B中,低位在A中。此指令下Cy总是为0。当结果大于255时,溢出标志位OV置1.
4.8、无符号整数除法指令
DIV AB; A/B->A(取整), 余数给B,Cy和OV清零,如果B=0,OV置1.
五、逻辑运算指令
5.1、累加器A清零指令
CLR A;不影响标志位。
5.2、累加器A求反指令
CPL A; 按位,逻辑取反,不影响标志位。
5.3、左循环移位指令
RL A; 循环,移位,位7循环移动到位0。不影响标志位。
5.4、带进位左循环移位指令
RLC A; 将A的内容和进位标志位Cy一块循环左移。
5.5、右循环移位指令
RR A ;循环,移位,位0循环移动到位7。不影响标志位。
5.6、带进位右循环移位指令
RRC A;将A的内容和进位标志位Cy一块循环右移。
5.7、逻辑与指令
ANL A,Rn; (A) 与 (Rn) -> A
5.8、逻辑或指令
ORL A,Rn;
5.9、逻辑异或指令
XRL A,Rn;
六、控制转移指令
6.1、长转移指令
LJMP addr16/标号; addr16 -> PC,程序无条件转向addr16指定的目的地址。但要注意跳转的范围最大为64KB。
6.2、相对转移指令
SJMO rel/标号;(PC) + rel -> rel;这是个2字节指令,rel为带符号八位相对偏移量。rel也可以用目的地址的标号来代替,此时的偏移量会由汇编程序自动计算。
6.3、绝对转移指令
AJMP addr11/标号;双字节指令
A10 A9 A8 0 0 0 0 1 A7 A6 A5 A4 A3 A2 A1 A0
A10~A0送入PC.10~PC.0;PC.15~PC.10保持00001B不变,形成16位转移目的地址。目的地址的高五位必须与PC高五位相同,否则将混乱。AJMP是2KB范围内的无条件跳转指令。
疑问:不是很理解是什么意思
6.4、间接跳转指令
JMP @A + DPTR; 单字节指令。
6.5、条件转移指令
满足对应的条件,则执行语句,如果不满足,则顺序执行下一条语句。
JZ rel; 如果累加器内容为0,则执行转移
JNZ rel;如果累加器内容非0,则执行转移
6.6、比较不相等转移指令
比较前两个操作数,如果不相等,则转向目的地址。
CJNE A,#date,rel;该指令不会对A 和date本身有任何改动。
6.7、减一不为0的转移指令
DJNZ Rn,rel;预先载入循环次数,实现按次数控制程序循环。
疑问:循环次数是哪个?程序的循环体是?
6.8、调用子程序指令
(1)长调用: LCALL addr16;3字节指令,先执行addr16地址的内容,在回来顺序执行下去,原本的,也就是被addr16插队的语句会被放入堆栈,低位先进。
(2)绝对调用:ACALL addr16;与AJMP 类似。
6.9、子程序的返回指令
RET;类似C语言函数中的return,在执行完LCALL/ACALL后,用RET把堆栈中存放的语句释放出来,开始执行。
6.10、中断返回指令
RETI;与RET类似,但清除了中断响应时被置1的优先寄存器。
疑问:中断响应?优先寄存器?没学到
6.11、空操作指令
NOP;(PC) + 1 -> PC;原地消耗一个机器周期。
七、位操作指令
7.1、数据位传送指令
MOV C,bit; MOV bit,C;
7.2、位变量修改指令
CLR C; Cy位清零 CLR bit;bit位清零
CPL C; Cy位求反 CPL bit;bit位求反
SETB C;Cy位置1 SETB bit;bit位置1;
不影响其他标志位。
7.3、位变量逻辑与指令
ANL C,bit;
7.4、为变量逻辑或指令
ORL C,bit;
/bit:对直接寻址位求反。
7.5、条件转移类指令
JC rel;进位标志位Cy = 1,则转移;
JNC rel;进位标志位Cy = 0,则转移
JB bit,rel; (bit)=1,则转移
JNB bit,rel;(bit)=0,则转移
JBC bit,rel;(bit)=1,则转移并把寻址位清零。
八、某些指令的说明
8.1、并行I/O口“读引脚”和“读锁存器”的区别
引用网络解释:
P0口的场效应管T2一端接地,一端与外部引脚相连,由P0的锁存器控制,当给锁存器写1时,它和地断开,写0时和地相连,所以写零时读到的总是低电平。如果p0口的场效应管T2一端接地的话,它会把p0口电位拉低,你读到的总是低电平0,所以要先给p0写FFH,把p0的场效应管T2和地断开,再读数时就是真实状态了。
MOV C,P1.0; MOV A,P1;是只读,读引脚
CPL P1.0; ANL P1,A 是读锁存器,即“读--修改--写”,类似的指令有:INC P1;XRL P3,A;
ORL P2,A;ANL P1,A; CPL P3.0;
8.2、操作数字节地址和位地址的区分
要分辨是字节地址还是位地址,看另一个操作数就可以了。例如:
MOV C,40H; C是位变量,所以40H也就是位地址
MOV A,40H;A是字节变量,所以40H也就是字节地址。
8.3、累加器A与ACC的书写
Acc,进行汇编后机器码含字节地址E0H,A汇编后字节地址会隐含在操作码中。
A 04H; ACC 05H E0H
对累加器A的直接寻址和位寻址要用Acc