目录
单片机中寻址是为了找到操作数,而各类指令则是为了对操作数进行操作。本篇文章将介绍51单片机中的第三类指令——逻辑操作类指令。
51 单片机的逻辑操作类指令是汇编语言编程里极为重要的一类指令,其主要功能是对 8 位二进制数开展逻辑运算。以下是对这些指令的详细介绍。
一、逻辑与指令(ANL)
指令格式:ANL 目的操作数 源操作数。此指令可对两个操作数进行按位逻辑与操作,结果存于目的操作数中。
(一) 指令格式及功能
1、ANL A, Rn
(1)功能:把累加器A中的内容和工作寄存器Rn(n = 0 - 7)中的内容按位进行逻辑与运算,运算结果存于累加器A中。
(2)示例代码
MOV A, #0F0H ; 将立即数 0F0H 送入累加器 A
MOV R0, #0FFH ; 将立即数 0FFH 送入寄存器 R0
ANL A, R0 ; A 和 R0 按位与,结果存于 A
(3)分析:A中的值为0F0H(二进制 11110000),R0中的值为0FFH(二进制11111111),按位与后结果为0F0H(二进制11110000),该结果存于累加器 A 中。
2、ANL A, direct
(1)功能:把累加器 A 中的内容与直接地址 direct 所指向单元中的内容按位进行逻辑与运算,运算结果存于累加器A中。
(2)示例代码
MOV A, #0F0H ; 将立即数 0F0H 送入累加器 A
MOV 30H, #0FFH ; 将立即数 0FFH 送入地址为 30H 的单元
ANL A, 30H ; A 和 30H 单元内容按位与,结果存于 A
(3)分析:同样,A的值为0F0H,地址30H单元的值为0FFH,按位与后结果为0F0H,该结果存于累加器 A 中。
3、ANL A, @Ri
(1)功能:把累加器A中的内容和以间接寻址寄存器Ri(i = 0, 1)所指向单元中的内容按位进行逻辑与运算,运算结果存于累加器A中。
(2)示例代码
MOV A, #0F0H ; 将立即数 0F0H 送入累加器 A
MOV 30H, #0FFH ; 将立即数 0FFH 送入地址为 30H 的单元
ANL A, 30H ; A 和 30H 单元内容按位与,结果存于 A
(3)分析:同样,A的值为0F0H,地址30H单元的值为0FFH,按位与后结果为0F0H,该结果存于累加器 A 中。
4、ANL A, #data
(1)功能:把累加器A中的内容和立即数data按位进行逻辑与运算,运算结果存于累加器A中。
(2)示例代码
MOV A, #0F0H ; 将立即数 0F0H 送入累加器 A
ANL A, #0FFH ; A 和立即数 0FFH 按位与,结果存于 A
(3)分析:A的值仍为0F0H。
5、ANL direct, A
(1)功能:把直接地址 direct 所指向单元中的内容和累加器A中的内容按位进行逻辑与运算,运算结果存于直接地址 direct 所指向的单元中。
(2)示例代码
MOV A, #0F0H ; 将立即数 0F0H 送入累加器 A
MOV 30H, #0FFH ; 将立即数 0FFH 送入地址为 30H 的单元
ANL 30H, A ; 30H 单元内容和 A 按位与,结果存于 30H 单元
(3)分析:地址30H单元的值变为0F0H。
6、ANL direct, #data
(1)功能:把直接地址direct所指向单元中的内容和立即数data按位进行逻辑与运算,运算结果存于直接地址direct所指向的单元中。
(2)示例代码
MOV 30H, #0FFH ; 将立即数 0FFH 送入地址为 30H 的单元
ANL 30H, #0F0H ; 30H 单元内容和立即数 0F0H 按位与,结果存于 30H 单元
(3)分析:地址30H单元的值变为0F0H。
(二)常见应用场景
1、清位操作:若要把某个寄存器或存储单元的特定位置为 0,就可以借助逻辑与指令。例如,要把累加器A的低 4 位清零,可使用指令ANL A, #0F0H。
2、屏蔽某些位:在读取端口数据时,若只关注其中的部分位,可利用逻辑与指令屏蔽其他位。例如,读取 P1 口数据,仅关注高 4 位,可使用指令ANL P1, #0F0H。
二、逻辑或指令(ORL)
指令格式:ORL 目的操作数 源操作数。此指令可对两个操作数进行按位逻辑或操作,结果存于目的操作数中。
(一) 指令格式及功能
1、基本指令格式
(1)ORL A, Rn :累加器 A 与寄存器 Rn 进行逻辑或操作,结果存于累加器 A。
(2)ORL A, direct :累加器 A 与直接地址单元内容进行逻辑或操作,结果存于累加器 A。
(3)ORL A, @Ri :累加器 A 与间接地址单元内容进行逻辑或操作,结果存于累加器 A。
(4)ORL A, #data :累加器 A 与立即数进行逻辑或操作,结果存于累加器 A。
(5)ORL direct, A :直接地址单元内容与累加器 A 进行逻辑或操作,结果存于直接地址单元。
(6)ORL direct, #data :直接地址单元内容与立即数进行逻辑或操作,结果存于直接地址单元。
2、示例代码
MOV A, #0F0H ; 把立即数 0F0H 送到累加器 A
MOV R0, #00FH ; 把立即数 00FH 送到寄存器 R0
ORL A, R0 ; 对 A 和 R0 进行按位或运算,结果存于 A
3、分析
A 的值为 0F0H(二进制 11110000),R0 的值为 00FH(二进制 00001111),按位或运算后结果为 0FFH(二进制 11111111),并存储在 A 中。
(二)常见应用场景
1、置位操作:若要把某个寄存器或存储单元的特定位置为 1,可使用逻辑或指令。例如,要将累加器 A 的低 4 位置 1,可使用指令 ORL A, #00FH。
2、合并信息:当需要把多个数据源的信息合并到一个寄存器或存储单元时,可使用逻辑或指令。例如,将两个不同的状态标志合并到一个字节中。
三、逻辑异或指令(ORL)
指令格式:XRL 目的操作数 源操作数。此指令可对两个操作数进行按位逻辑异或操作,结果存于目的操作数中。
(一) 指令格式及功能
1、基本指令格式
(1)XRL A, Rn :累加器 A 与寄存器 Rn 进行逻辑异或操作,结果存于累加器 A。
(2)XRL A, direct :累加器 A 与直接地址单元内容进行逻辑异或操作,结果存于累加器 A。
(3)XRL A, @Ri :累加器 A 与间接地址单元内容进行逻辑异或操作,结果存于累加器 A。
(4)XRL A, #data :累加器 A 与立即数进行逻辑异或操作,结果存于累加器 A。
(5)XRL direct, A :直接地址单元内容与累加器A进行逻辑异或操作,结果存于直接地址单元。
(6)XRL direct, #data :直接地址单元内容与立即数进行逻辑异或操作,结果存于直接地址单元。
2、示例代码
MOV A, #0F0H ; 把立即数 0F0H 送入累加器 A
MOV R0, #00FH ; 把立即数 00FH 送入寄存器 R0
XRL A, R0 ; 对 A 和 R0 进行按位异或运算,结果存于 A
3、分析
A的值为0F0H(二进制11110000),R0的值为00FH(二进制00001111),按位异或后结果是0FFH(二进制11111111),存于A中。
(二)常见应用场景
1、取反操作:可以通过与全 1 数据进行异或运算来对某个寄存器或存储单元的内容取反。例如,要对累加器A的内容取反,可使用XRL A, #0FFH。
2、判断两数是否相同:对两个数进行异或运算,如果结果为 0,则这两个数相同。在实际应用中,可用于检查数据是否发生变化。
3、加密和解密:简单的加密可以通过将数据与一个密钥进行异或运算实现,解密时再次进行相同的异或运算即可恢复原始数据。
四、累加器清 0 指令 CLR A
1、功能
此指令的作用是把累加器 A 中的内容清零,也就是让 A 的值变为 00H。该指令属于单字节指令。这是专门用于清零累加器的指令,指令简单直接,机器码只有一个字节,执行速度快,在仅需清零累加器的场景中是最佳选择。
2、示例代码
MOV A, #0FFH ; 把立即数 0FFH 送到累加器 A
CLR A ; 将累加器 A 清零
3、分析
① 执行 MOV A, #0F0H 后,A 的值为 0F0H(二进制 11110000)。
② 接着执行 CLR A 指令,累加器 A 的值就变为 00H (二进制 00000000 )。
五、累加器取反指令 CPL A
1、功能
该指令能对累加器A中的每一位进行取反操作,即原本为0的位变为1,原本为1的位变为0。该指令属于单字节指令。
2、示例代码
MOV A, #0F0H ; 将立即数 0F0H 送入累加器 A
CPL A ; 对累加器 A 的内容进行取反操作
3、分析
① 执行MOV A, #0F0H后,累加器A的值为0F0H(二进制11110000)。
② 执行CPL A后,A的每一位取反,结果变为0FH(二进制00001111)。
六、累加器半字节交换指令 SWAP A
在 51 单片机的汇编语言里,累加器半字节交换指令是很实用的逻辑操作类指令,它主要用于实现累加器A中高 4 位和低 4 位数据的交换。
1、功能
此指令能将累加器A的高 4 位(D7 - D4)与低 4 位(D3 - D0)进行交换,而不会影响标志位。该指令属于单字节指令。
2、示例代码
MOV A, #3AH ; 把立即数 3AH 送入累加器 A
SWAP A ; 对累加器 A 进行半字节交换操作
3、代码分析
① 执行MOV A, #3AH后:累加器A的值为3AH(二进制00111010)。
② 执行SWAP A后:A的高 4 位和低 4 位进行交换,A的值变为A3H(二进制1010 0011)。
4、应用场景
(1)数据拆分与合并:在处理一些需要把一个字节数据拆分成两个半字节数据,或者将两个半字节数据合并成一个字节数据的场景中,该指令十分有用。例如,要把一个字节数据的高 4 位和低 4 位分别存到不同的存储单元,就可以先使用SWAP A指令,再进行存储操作。
(2)编码转换:在某些编码转换算法里,可能需要对字节数据的高 4 位和低 4 位进行位置调整,此时使用SWAP A指令能快速实现。
(3)BCD 码处理:在处理 BCD 码(二进制编码的十进制数)时,一个字节通常包含两个 BCD 码(高 4 位和低 4 位各一个)。若需要交换这两个 BCD 码的位置,就可以使用SWAP A指令。
七、环移指令
环移指令是重要的逻辑操作类指令,用于对累加器 A 中的数据进行循环移位操作。这类指令可以高效地实现数据的位操作,在数据处理、加密算法等场景中具有广泛的应用。
(一)不带进位的循环左移指令:RL A
1、功能
将累加器 A 中的内容循环左移一位,即 A 的最高位(D7)移入最低位(D0),同时其他位依次左移一位。该指令不影响进位标志 CY。
2、示例代码
MOV A, #01H ; 将立即数 01H 送入累加器 A
RL A ; 对累加器 A 进行循环左移操作
3、分析
① 执行 MOV A, #01H 后,A 的值为 01H(二进制 00000001)。
② 执行 RL A 后,A 的值变为 02H(二进制 00000010)。
(二)不带进位的循环右移指令:RR A
1、功能
将累加器 A 中的内容循环右移一位,即 A 的最低位(D0)移入最高位(D7),同时其他位依次右移一位。该指令不影响进位标志 CY。
2、示例代码
MOV A, #02H ; 将立即数 02H 送入累加器 A
RR A ; 对累加器 A 进行循环右移操作
3、分析
① 执行 MOV A, #02H 后,A 的值为 02H(二进制 00000010)。
② 执行 RR A 后,A 的值变为 01H(二进制 00000001)。
(三)带进位的循环左移指令:RLC A
1、功能
将累加器 A 中的内容和进位标志 CY 一起进行循环左移一位,即 A 的最高位(D7)移入进位标志 CY,CY 的原来值移入 A 的最低位(D0),同时其他位依次左移一位。
2、示例代码
MOV A, #01H ; 将立即数01H送入累加器A
SETB C ; 将进位标志CY置为1
RLC A ; 对累加器A进行带进位的循环左移操作
3、分析
① 执行 MOV A, #01H 后,A 的值为 01H,即二进制 00000001。
② 执行 SETB C 后,CY 的值为 1。
③ 执行 RLC A 指令时,A 的最高位 0 移入 CY,CY 的原来值 1 移入 A 的最低位,其他位依次左移一位,所以执行完后 A 的值变为 81H(二进制 10000001),CY 的值变为 0。
(四)带进位的循环右移指令 RRC A
1、功能
将累加器 A 中的内容和进位标志 CY 一起进行循环右移一位,即 A 的最低位(D0)移入进位标志 CY,CY 的原来值移入 A 的最高位(D7),同时其他位依次右移一位。
2、示例代码
MOV A, #80H ; 将立即数80H送入累加器A
SETB C ; 将进位标志CY置为1
RRC A ; 对累加器A进行带进位的循环右移操作
3、分析
① 执行 MOV A, #80H 后,A 的值为 80H,即二进制 10000000。
② 执行 SETB C 后,CY 的值为 1。
③ 执行 RRC A 指令时,A 的最低位 0 移入 CY,CY 的原来值 1 移入 A 的最高位,其他位依次右移一位,所以执行完后 A 的值变为 40H(二进制 01000000),CY 的值变为 0。