10课单片机数据传送类指令
- 格式:doc
- 大小:26.50 KB
- 文档页数:5
3.2.1 数据传送类指令数据传送指令用于实现寄存器与存储器之间、寄存器之间、累加器AL/AX与I/O端口之间、立即数到寄存器或存储器之间的字节或字的传送。
这类指令的共同特点是不影响标志寄存器的内容(SAHF,POPF除外)。
堆栈操作指令、标志位传送指令和地址传送指令也归入这一类中,共14条指令,又可分为4组,如表3.4所示。
1.通用数据传送指令通用数据传送指令包括传送指令MOV、堆栈操作指令PUSH、POP、输入/输出指令(累加器传送指令)、数据交换指令XCHG和查表转换指令XLAT。
这类指令是唯一允许以段寄存器作为操作数的指令(XCHG除外)。
表3.4 数据传送类指令指令类型指令书写格式指令功能通用数据传送指令MOV 目标,源PUSH 源POP 目标XCHG 目标,源XLAT 字节或字传送字压入堆栈字弹出堆栈字节或字交换字节翻译目标地址传送指令LEA 目标,源LDS 目标,源LES 目标,源装入有效地址装入DS寄存器装入ES寄存器标志位传送指令LAHFSAHFPUSHFPOPF 将FR低字节装入AH寄存器将AH内容装入FR低字节将FR内容压入堆域从堆栈弹出FR内容I/O数据传送指令IN 累加器,端口OUT 端口,累加器从端口输入字节或字将字节或字输出到端口(1)MOV 传送指令指令格式:MOV OPD,OPS指令功能:将源操作数OPS传送到目的操作数OPD,即(OPD)→(OPS)。
源操作数OPS可以是8/16位的通用寄存器、段寄存器、存储器中某单元或8/16位的立即数。
(2)PUSH进栈(压入)指令指令格式:PUSH OPS指令功能:将源操作数OPS压入堆栈,即SP–2 → SP,OPS → (SPH,SP)。
源操作数0PS可以是16位通用寄存器、段寄存器或存储器中的数据字,以保证堆栈按“字”操作。
源操作数OPS不能是立即数。
由于堆栈是按“后进先出”方式工作,所以每次执行PUSH指令时,总是首先修改栈指针(S P)–2 → SP (即SP先减2),使之指向新栈顶,然后把源操作数压入堆栈中SP所指示的位置,高字节在较高地址单元,低字节在较低地址单元中(真正的栈顶单元)。
单片机指令大全- - 指令格式功能简述字节数周期一、数据传送类指令MOV A, Rn 寄存器送累加器 1 1MOV Rn,A 累加器送寄存器 1 1MOV A ,@Ri 内部RAM单元送累加器 1 1MOV @Ri ,A 累加器送内部RAM单元 1 1MOV A ,#data 立即数送累加器 2 1MOV A ,direct 直接寻址单元送累加器 2 1MOV direct ,A 累加器送直接寻址单元 2 1MOV Rn,#data 立即数送寄存器 2 1MOV direct ,#data 立即数送直接寻址单元 3 2MOV @Ri ,#data 立即数送内部RAM单元 2 1MOV direct ,Rn 寄存器送直接寻址单元 2 2MOV Rn ,direct 直接寻址单元送寄存器 2 2MOV direct ,@Ri 内部RAM单元送直接寻址单元 2 2 MOV @Ri ,direct 直接寻址单元送内部RAM单元 2 2 MOV direct2,direct1 直接寻址单元送直接寻址单元 3 2 MOV DPTR ,#data16 16位立即数送数据指针 3 2 MOVX A ,@Ri 外部RAM单元送累加器(8位地址) 1 2 MOVX @Ri ,A 累加器送外部RAM单元(8位地址) 1 2 MOVX A ,@DPTR 外部RAM单元送累加器(16位地址) 1 2MOVX @DPTR ,A 累加器送外部RAM单元(16位地址) 1 2 MOVC A ,@A+DPTR 查表数据送累加器(DPTR为基址) 1 2 MOVC A ,@A+PC 查表数据送累加器(PC为基址) 1 2 XCH A ,Rn 累加器与寄存器交换 1 1XCH A ,@Ri 累加器与内部RAM单元交换 1 1 XCHD A ,direct 累加器与直接寻址单元交换 2 1XCHD A ,@Ri 累加器与内部RAM单元低4位交换 1 1 SWAP A 累加器高4位与低4位交换 1 1POP direct 栈顶弹出指令直接寻址单元 2 2PUSH direct 直接寻址单元压入栈顶 2 2二、算术运算类指令ADD A, Rn 累加器加寄存器 1 1ADD A,@Ri 累加器加内部RAM单元 1 1ADD A, direct 累加器加直接寻址单元 2 1ADD A, #data 累加器加立即数 2 1ADDC A, Rn 累加器加寄存器和进位标志 1 1ADDC A,@Ri 累加器加内部RAM单元和进位标志 1 1 ADDC A, #data 累加器加立即数和进位标志 2 1 ADDC A, direct 累加器加直接寻址单元和进位标志 2 1INC A 累加器加1 1 1INC Rn 寄存器加1 1 1INC direct 直接寻址单元加1 2 1INC @Ri 内部RAM单元加1 1 1INC DPTR 数据指针加1 1 2DA A 十进制调整 1 1SUBB A, Rn 累加器减寄存器和进位标志 1 1 SUBB A,@Ri 累加器减内部RAM单元和进位标志 1 1 SUBB A, #data 累加器减立即数和进位标志 2 1 SUBB A, direct 累加器减直接寻址单元和进位标志 2 1 DEC A 累加器减1 1 1DEC Rn 寄存器减1 1 1DEC @Ri 内部RAM单元减1 1 1DEC direct 直接寻址单元减1 2 1MUL AB 累加器乘寄存器B 1 4DIV AB 累加器除以寄存器B 1 4三、逻辑运算类指令ANL A, Rn 累加器与寄存器 1 1ANL A,@Ri 累加器与内部RAM单元 1 1ANL A, #data 累加器与立即数 2 1ANL A, direct 累加器与直接寻址单元 2 1ANL direct, A 直接寻址单元与累加器 2 1ANL direct, #data 直接寻址单元与立即数 3 1ORL A, Rn 累加器或寄存器 1 1ORL A,@Ri 累加器或内部RAM单元 1 1ORL A,#data 累加器或立即数 2 1 ORL A,direct 累加器或直接寻址单元 2 1 ORL direct, A 直接寻址单元或累加器 2 1 ORL direct, #data 直接寻址单元或立即数 3 1 XRL A, Rn 累加器异或寄存器 1 1XRL A,@Ri 累加器异或内部RAM单元 1 1 XRL A,#data 累加器异或立即数 2 1 XRL A,direct 累加器异或直接寻址单元 2 1 XRL direct, A 直接寻址单元异或累加器 2 1 XRL direct, #data 直接寻址单元异或立即数 3 2 RL A 累加器左循环移位 1 1RLC A 累加器连进位标志左循环移位 1 1 RR A 累加器右循环移位 1 1RRC A 累加器连进位标志右循环移位 1 1 CPL A 累加器取反 1 1CLR A 累加器清零 1 1四、控制转移类指令类ACCALL addr11 2KB范围内绝对调用 2 2 AJMP addr11 2KB范围内绝对转移 2 2 LCALL addr16 2KB范围内长调用 3 2 LJMP addr16 2KB范围内长转移 3 2 SJMP rel 相对短转移 2 2JMP @A+DPTR 相对长转移 1 2RET 子程序返回 1 2RET1 中断返回 1 2JZ rel 累加器为零转移 2 2JNZ rel 累加器非零转移 2 2CJNE A ,#data ,rel 累加器与立即数不等转移 3 2 CJNE A ,direct ,rel 累加器与直接寻址单元不等转移 3 2 CJNE Rn,#data ,rel 寄存器与立即数不等转移 3 2 CJNE @Ri ,#data,rel RAM单元与立即数不等转移 3 2 DJNZ Rn ,rel 寄存器减1不为零转移 2 2 DJNZ direct ,rel 直接寻址单元减1不为零转移 3 2 NOP 空操作 1 1五、布尔操作类指令MOV C, bit 直接寻址位送C 2 1MOV bit, C C送直接寻址位 2 1CLR C C清零 1 1CLR bit 直接寻址位清零 2 1CPL C C取反 1 1CPL bit 直接寻址位取反 2 1SETB C C置位 1 1SETB bit 直接寻址位置位 2 1ANL C, bit C逻辑与直接寻址位 2 2ANL C, /bit C逻辑与直接寻址位的反 2 2ORL C, bit C逻辑或直接寻址位 2 2ORL C, /bit C逻辑或直接寻址位的反 2 2JC rel C为1转移 2 2JNC rel C为零转移 2 2JB bit,rel 直接寻址位为1转移 3 2JNB bit,rel 直接寻址为0转移 3 2JBC bit,rel 直接寻址位为1转移并清该位 3 2单片机MCS-51系列指令快速记忆法随着微电子技术和超大规模集成电路技术的发展,单片微型计算机以其体积小、性价比高、功能强、可靠性高等独有的特点,在各个领域(如工业控制、家电产品、汽车电子、通信、智能仪器仪表)得到了广泛的应用。
引言概述:单片机指令是嵌入式系统设计中至关重要的一部分,它们定义了单片机的功能和操作。
本文是单片机指令大全系列的第二部分,旨在提供更多全面的单片机指令信息,帮助读者更好地理解和应用单片机指令。
正文内容:一、移位指令1.逻辑左移指令:将操作数的每一位向左移动一位,并且最低位填充0。
2.逻辑右移指令:将操作数的每一位向右移动一位,并且最高位填充0。
3.算术右移指令:将操作数的每一位向右移动一位,并且最高位保持不变。
4.循环左移指令:将操作数的每一位向左循环移动一位,即最高位移动到最低位。
5.循环右移指令:将操作数的每一位向右循环移动一位,即最低位移动到最高位。
二、逻辑运算指令1.逻辑与指令:对操作数进行逻辑与运算,将两个二进制数对应位上的值进行逻辑与操作。
2.逻辑或指令:对操作数进行逻辑或运算,将两个二进制数对应位上的值进行逻辑或操作。
3.逻辑非指令:对操作数进行逻辑非运算,将二进制数的每一位取反。
4.逻辑异或指令:对操作数进行逻辑异或运算,将两个二进制数对应位上的值进行逻辑异或操作。
5.逻辑移位指令:将操作数进行逻辑左移或右移。
三、算术运算指令1.加法指令:对操作数进行加法运算,并将运算结果保存到指定的寄存器或存储器中。
2.减法指令:对操作数进行减法运算,并将运算结果保存到指定的寄存器或存储器中。
3.乘法指令:对操作数进行乘法运算,并将运算结果保存到指定的寄存器或存储器中。
4.除法指令:对操作数进行除法运算,并将运算结果保存到指定的寄存器或存储器中。
5.移位指令:对操作数进行移位运算,包括算术左移、算术右移、循环左移和循环右移。
四、输入输出指令1.读取输入指令:从指定的输入设备读取数据,并将数据保存到指定的寄存器或存储器中。
2.输出显示指令:将指定的数据从寄存器或存储器中读取,并显示到指定的输出设备上。
3.端口输入指令:从指定的端口读取数据,并将数据保存到指定的寄存器或存储器中。
4.端口输出指令:将指定的数据从寄存器或存储器中读取,并输出到指定的端口上。
一、数据传送类指令(8种助记符)MOV(英文为Move):对内部数据寄存器RAM和特殊功能寄存器SFR的数据进行传送;P55PUSH (Push onto Stack) 入栈;PUSH directPOP (Pop from Stack) 出栈;POP directXCH (Exchange) 字节交换;XCH A,源/@RiXCHD (Exchange low-order Digit) 低半字节交换;同上SWAP (Swap) 低4位与高4位交换;SWAP A MOVC(Move Code)读取程序存储器数据表格的数据传送;MOVC A,@A+DPTR/PC MOVX (Move External RAM) 对外部RAM的数据传送;MOVX @DPTR,A MOVX A,@DPTR/@Ri MOVX @Ri,A二、算术运算类指令(8种助记符)ADD(Addition) 加法;ADDC(Add with Carry) 带进位加法;INC(Increment) 加1;INC A/Rn/direct/@Ri/源/DPTRDA(Decimal Adjust) 十进制调整;SUBB(Subtract with Borrow) 带借位减法;DEC(Decrement) 减1;DEC A/Rn/direct/@Ri/源MUL(Multiplication、Multiply) 乘法;MUL AB 高B,低A。
Cy=0 大于256,OV=1 DIV(Division、Divide) 除法;DIV AB 商A,余B。
Cy=0 OV=B(同上)三、逻辑运算类指令(9种助记符)CLR(Clear) 清零;CLR ACPL(Complement) 取反;CPL ARL(Rotate left) 循环左移;(同上)RLC(Rotate Left throught the Carry flag) 带进位循环左移;(同上)RR(Rotate Right) 循环右移;(同上)RRC (Rotate Right throught the Carry flag) 带进位循环右移;(同上)ANL(AND Logic) 逻辑与;ANL A,#data/Rn/direct/@Ri ANL direct,A/#dataORL(OR Logic) 逻辑或;ORL A,#data/Rn/direct/@Ri ANL direct,A/#dataXRL(Exclusive-OR Logic) 逻辑异或;(同上)四、位操作指令(6种助记符)MOV 位数据传送指令;MOV C,bit MOV bit,CCLR 位清零;C bitSETB(Set Bit)位置1;C bitCPL位取反;(同上)ANL位逻辑运算指令;ANL C,bit//bitORL位逻辑或运算指令;(同上)五、控制转移类指令(18种助记符)AJMP(Absolute Jump)绝对转移;AJMP addr11/ LABELLJMP(Long Jump)长转移;(同上)SJMP(Short Jump)短转移;SJMP rel/ LABELJMP间接转移指令; JMP @A+DPTRJZ (Jump if Zero)结果为0则转移;JZ rel/ LABELJNZ (Jump if Not Zero) 结果不为0则转移;(同上)CJNE (Compare Jump if Not Equal)比较不相等则转移;CJNE A,direct,rel/ LABEL CJNE A/Rn/@Ri,#data,rel/ LABELJC (Jump if the Carry flag is set)有进位则转移;JC rel/ LABELJNC (Jump if Not Carry)无进位则转移;(同上)JB (Jump if the Bit is set)位为1则转移;JB bit, rel/ LABELJNB (Jump if the Bit is Not set) 位为0则转移;(同上)JBC(Jump if the Bit is set and Clear the bit) 为1则转移,并清除该位;DJNZ (Decrement Jump if Not Zero)减1后不为0则转移;DJNZ Rn,rel/ LABEL DJNZ direct,rel/ LABELLCALL(Long subroutine Call)子程序长16调用;LCALL addr16/ SUBROUTINEACALL(Absolute subroutine Call)子程序绝对11调用;(同上)RET(Return from subroutine)子程序返回;RETI(Return from Interruption)中断返回;NOP (No Operation) 空操作;8种常用伪指令1.ORG 16位地址;此指令用在原程序或数据块的开始,指明此语句后面目标程序或数据块存放的起始地址。
单片机数据传送指令【教学目标】1、认知目标(1)了解项目设计的过程;(2)掌握单片机程序基本格式;(3)掌握数据传送指令;2、技能目标掌握单片机程序设计基本格式。
3、能力目标对学生思维能力进行拓展,激发他们探索单片机奥秘的欲望。
【教学重点】(1)项目设计的过程(2)单片机程序基本格式【教学难点】(1)单片机程序基本格式(2)数据传送指令使用方法【教学方法】讲授法项目法【授课地点】普通教室,不使用多媒体【教学过程】一、复习引入新课复习单片机基本结构与组成。
提问:生活中的一盏灯是如何控制的?学生思考回答:引出我们能否使用单片机控制的方式来实现?学生思考…………。
二、切入课堂内容1、数据传送类指令作用:将数据传送到相应端口输出。
格式:MOV 【目的操作数】,【源操作数】1传送方向:目的操作数 源操作数例:MOV A #55H ;将55H传送到累加器A中2、实例项目点亮P1.0所接LED灯(1)项目分析:LED图中可知:欲使LED灯点亮,即P1.0端口输出高电平,即输出1即可。
由上表可得,即送给P1口的数据为01H即可点字亮P1.0端口所接LED灯。
(2)设计流程图(3)编写程序程序格式:ORG 0000H ;程序从0000H单元开始2LJMP MAIN ;跳转到MAIN处执行ORG 0030H ;数据存放从0030H单元开始MAIN: ;MAIN标号MOV P1,#01H ;将01H送入P1口,显示P1.0所接LEDLJMP MAIN ;跳转到MAIN处执行END ;程序结束3、拓展思维(1)如何点亮P1口所接8只LED灯。
(2)如何实现P1口所接8只LED灯向左依次点亮(流水灯)。
【教学反思】本节课程重点讲授一个简单项目,从而使学生对单片机开发有更直接的理解。
用实现讲解指令,比单独讲解指令更明确,更容易理解其作用和用法。
3。
单片机指令的数据传输和存储操作随着科技的不断发展,单片机在电子设备中的应用越来越广泛。
在单片机的编程过程中,数据传输和存储操作是非常重要的一部分。
本文将重点介绍单片机指令中的数据传输和存储操作,并以此为基础探讨其在电子设备中的应用。
一、数据传输操作数据传输操作是指将数据从一个位置传输到另一个位置的操作。
单片机中的数据传输操作通常涉及到寄存器之间、寄存器和内存之间、以及IO口之间的传输。
1. 寄存器与寄存器之间的数据传输在单片机中,数据传输操作可以通过MOV指令实现。
MOV指令用于将一个源操作数中的数据传送到一个目的操作数中。
源操作数和目的操作数都可以是寄存器。
例如,MOV A, B将寄存器B的数据传送到寄存器A中。
2. 寄存器和内存之间的数据传输除了寄存器与寄存器之间的数据传输,单片机还经常需要进行寄存器和内存之间的数据传输。
在单片机中,可以使用LDA(Load Accumulator)和STA(Store Accumulator)指令来进行数据传输。
LDA指令用于将一个内存单元中的数据传送到累加器中,例如LDA 2000H将内存地址2000H中的数据传送到累加器中。
而STA指令则用于将累加器中的数据传送到一个内存单元中,例如STA 3000H将累加器中的数据传送到内存地址3000H中。
3. IO口之间的数据传输在许多电子设备中,单片机需要与外部设备进行数据传输,这时可以使用IN(输入)和OUT(输出)指令来实现。
IN指令用于将外部设备的数据传送到累加器中,例如IN A, P0将P0口上的数据传送到累加器A中。
而OUT指令则用于将累加器中的数据传送到外部设备的端口上,例如OUT P1, A将累加器A的数据传送到P1口上。
二、数据存储操作数据存储操作是指将数据保存到某个位置的操作。
在单片机中,数据存储操作通常涉及到寄存器、内存和IO口。
1. 寄存器的数据存储在单片机中,寄存器是存储数据的重要部分。
单片机常用指令在单片机编程中,常用的指令是一种用于控制微处理器和外围设备工作的基本命令。
掌握常用指令对于单片机的开发和应用至关重要。
本文将介绍一些常用的单片机指令,以帮助读者更好地理解和应用单片机。
一、数据传输指令1. MOVMOV指令用于将一个操作数的值传送到另一个操作数,格式为MOV 目的操作数,源操作数。
例如:MOV A,B表示将寄存器B中的值传送到寄存器A中。
2. LDA和STALDA指令用于将一个内存单元的值传送到累加器A中,格式为LDA 内存单元地址。
例如:LDA 0x1234表示将0x1234地址处的数据传送到累加器A中。
STA指令与LDA相反,用于将累加器A的值传送到一个内存单元中,格式为STA 内存单元地址。
3. LXILXI指令用于将一个16位的立即数装入16位寄存器,格式为LXI 寄存器对,16位立即数。
例如:LXI BC,0x1234表示将0x1234装入BC寄存器。
二、算术逻辑指令1. ADD和SUBADD指令用于将一个操作数的值与累加器A的值相加,结果存放在累加器A中,格式为ADD 操作数。
例如:ADD B表示将寄存器B的值与累加器A的值相加。
SUB指令与ADD相反,用于将一个操作数的值减去累加器A的值,结果存放在累加器A中,格式为SUB 操作数。
2. INR和DCRINR指令用于将一个操作数的值增加1,格式为INR 操作数。
例如:INR C表示将寄存器C的值加1。
DCR指令与INR相反,用于将一个操作数的值减1,格式为DCR操作数。
3. AND和ORAND指令用于将一个操作数的值与累加器A的值按位与运算,结果存放在累加器A中,格式为AND 操作数。
例如:AND D表示将寄存器D的值与累加器A的值按位与运算。
OR指令与AND相反,用于将一个操作数的值与累加器A的值按位或运算,结果存放在累加器A中,格式为OR 操作数。
三、分支指令1. JMPJMP指令用于无条件地跳转到指定的内存地址,格式为JMP 内存地址。
数据传送指令详解前言上一章我们说了汇编语言的基础,包括数据格式,寄存器以及操作数的标识方式,接下来我们就应该去认识一下hiU币按语言当红真难过的格各个指令了.这些指令大部署很简单,但是组合在一起却能模拟出我们程序当中香烟的任何效果,确实很神奇.数据传送指令数据传送指令的目的是我了将一个数据从一个位置复制到另一个位置.既然如此,那么数据传送至零就会包含一个源操作数和一个目的操作数,指令会将源操作数的值复制到目的操作数并覆盖.数据传送指令一共可以分为5种,分别是mov,movs,movz,push以及pop.如果你多少懂一点编程语言的话,看名字就能知道一个大概,不过在这里我还是说一下各个指令的作用.mov指令mov指令的作用是将源操作数S中的数据复制到目的操作数D 中,mov指令有一个数据格式和两个操作数,因此一般的形式为[movx S D].其中x为数据格式,S为源操作数,D为目的操作数.举个简单的案例,比如我们有一条指令为movl %edx %eax.那么他的执行过程如下图所示:可以看到,在指令执行之后,%edx寄存器当中的内容就会被复制到%eax寄存器.需要一提的是,mov指令可以在后面加上任何数据格式,比如上面这一过程中,数据格式为4个字节,也就是双字.因此不难推断出,我们还可以使用movb和movw去复制一个字节或两个字节.movs指令movs指令的作用是将源操作数S中的数据做符号扩展后,再复制到目的操作数D中,movs指令有两个数据格式和两个操作数,因此一般的形式为[movsxy S D].其中x,y位数据格式,S为源操作数,D为目的操作数.其中x,y的组合一共有三种,分别是bw,bl,wl,这三个组合代表的意思分别是单字节到双字节,单字节到双字以及双字节到双字.还是举个例子,对于指令movswl %dx %eax来说,它的作用如下图:这里为了看出来符号位的扩展,因为我们在这里使用了十六进制的整数表示方式.可以看到,movs指令将0x8FFF扩展以后存入%eax寄存器,其中%dx为寄存器%edx的后16位表示.movz指令movz指令的作用是将源操作数S做零扩展后,再复制到目的操作数中.它与movs指令十分相似,也有两个数据格式和两个操作数,因此一般形式为[movzxy S D].各个字母代表的含义和movsxy代表的一样.还是看案例,对于指令movzwl %dx %eax来说,他的作用和上面的movs有何不同.可以看出,movs和movz指令十分相似,只是这里扩展后,目标寄存器%eax的前16位是0而不是1.push指令push指令与上面的mov族的指令不同,他的目的是操作数被固定为栈顶,因此他的指令当中没有目的操作数另外友谊县需要注意,他在进行复制操作之前,需要移动栈顶指针(-4).push指令的一般形式为[pushl S],其中l代表数据格式为双字,S为源操作数,目的操作数默认为栈顶案例,比如pushl %edx这条指令,他的任务是将%edx寄存器的值复制到栈顶.我们首先来看一下命令执行前,寄存器以及存储器的状态.可以看到,寄存器%ebp和%esp分别指向帧指针和栈指针,而%esp 实际上就是指向栈顶.由于现在栈顶位于-16的位置,因此若要将%dex 压入栈,则现需要将栈顶移动到-20的位置,然后再进行赋值,移动后的状态如下所示:可以看到,这里的栈指针的位置已经发生了变化,向下移动了四位,并且将%edx寄存器的值放入新的栈顶,因此pushl %edx指令就相当于下面两条指令:subl $4,%espmovl %edx,(%esp)这里可以看出,其实push指令做了一个隐藏操作,就是移动栈指针(-4),这一点希望能引起大家的注意.坚持住,还有最后一个命令!pop指令pop指令与push指令的做的相反的操作,一个是入栈一个是出栈.对于pop指令来说,他的源操作数背负定位栈顶,相反,它会先进行复制操作,然后再移动栈指针.pop指令的一般形式为[popl D],其中l代表数据类型,D为目的操作数,源操作数默认为栈顶.案例,考虑popl %edx这条指令的效果,他会将栈顶的值弹出到寄存器%edx.首先来看执行之前,寄存器以及存储器的状态.接下来执行pop指令时,会相减栈顶的值复制到%edx,然后在将栈指针移动( 4).我们来看一下它执行后的状态.可以看到,之前栈顶的内容已经被弹出到%edx寄存器,并且当前栈顶已经移动到了-16的位置,也就是进行了4操作.因此popl %edx指令就相当于下面这两条指令:movl (%esp),%edxaddl $4,%esp这里能够看出,其实popl指令也同样做了一个隐藏的操作,就是移动栈指针( 4).说了很多,貌似有人会说都是花架子,下面咱们就结合具体的案例来看看数据复制示例上面我们说了几乎所有的复制指令,接下来的一小段代码,让我们来看一下这些数据指令,如何完成我们的程序操作.simple(int *xp,int y){int t=*xp;*xp=y;return t;}上面是一个简单的C语言程序,它其中包含了一些复制操作,我们来看看他的汇编代码.使用GCC -O1 -S sum.c来获取我们的汇编代码,并使用cat sum.c来查看一下:.file 'sum.c'.text.globl simple.type simple, @functionsim ple:pushl %ebpmovl %esp, %ebp//以上为栈的建立部分movl 8(%ebp), %edxmovl (%edx), %eaxmovl 12(%ebp), %ecxmovl %ecx, (%edx)//以下为栈的完成部分popl %ebpret.size simple, .-simple.ident 'GCC: (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3'.section .note.GNU-stack,'',@progbits分析这段汇编代码的时候,我们应该分为三个部分来看待,首先是栈的建立,然后是使用,最后是完成部分.看到这里,里面几乎全是数据复制指令,我们先开看看栈的建立部分.其实地狱与一开始pushl和movl指令来说,他们主要做了两件事.第一个是将原来的帧指针备份到栈顶,然后再将栈指针和帧指针统一指向这个新的栈顶,也就是完成了一个新站的建立.它在完成后,栈的状态如下所示.可以看到,寄存器%ebp和寄存器%esp都指向当前栈指针的位置,其中变量xp位于 8的位置,而y位于 12的位置.由于xp是一个指针变量,因此它会指向一个内存中的区域,其中的值为*xp.了解完寄存器和存储器的转台,此时栈已经建立完毕,接下来我们看紧接着的一句汇编代码的作用.movl 8(%ebp),%edx这一句将内存地址为%ebp 8的值复制到%edx,很明显,从上面的图中可以看出,%ebp 8这个位置存储着xp变量.这一句指令做了一个简单的操作,就是将xo提取到%edx寄存器,如下所示:此时已经将%edx的值改变为了变量xp,看接下来的一句操作.movl (%edx) ,%eax这一句话将内存地址为%edx的值赋给类寄存器%eax,并准备返回值.此时%edx寄存器的值已经改变为了xp变量,因此(%edx)其实就是*xp,而%eax寄存器一般回座位函数的返回值,因此他其实代替了临时变量t.执行后的状态如下所示.此时其实已经完成了程序中的int t=*xp以及为return t准备好了返回值,接下来的一句汇编代码也很简单,如下.movl 12(%ebp),%ecx它的作用是将地址为%ebp 12的值复制到寄存器%ecx,从图中可以看出,%ebp 12就是存储的变量y.因此他的作用就是将y复制到寄存器%ecx,如下所示:上面这一步很简单,我们来看最后一步操作,如下:movl %ecx ,(%edx)他的作用是将%ecx寄存器的值复制到内存中%edx的位置.此时%ecx的值为y,而%edx中为xp,因此目的操作数则为xp执行的位置,也就是*xp.这一句话执行的就是程序代码当中*xp=y这个操作,它执行后的状态如下所示:可以看到,在执行了*xp=y以后,xp指针所指向的位置,其值已经变成了y.此时程序其中已经基本运行完毕,剩下的工作也就是栈的完成操作了,也就是popl指令.在栈完成之后,也就是pop指令执行之后,当前帧会恢复到调用者的帧上面去,如下所示:此时当前帧已经恢复到了调用者的帧,最后ret指令会改变程序计数器(PC)的值,然后跳出子函数,继续执行调用者当中的代码.到此,我们的数据复制实力就完成了,尽管着了例子不难,但是很能够说明问题,只要能了解了这个过程,相信一些复杂的汇编指令也只是分析的时间长点罢了.小小的结一下一般人家都说,字不如表,表不如图,有了这么多的好图,你肯定想求个种子啥的对吧,这不是让你看图猜链接....。
格式功能简述字节数周期一、数据传送类指令MOVA,Rn寄存器送累加器11MOVRn,A累加器送寄存器11MOVA,@Ri内部RAM单元送累加器11MOV@Ri,A累加器送内部RAM单元11MOVA,#data立即数送累加器21MOVA,direct直接寻址单元送累加器21MOVdirect,A累加器送直接寻址单元21MOVRn,#data立即数送寄存器21MOVdirect,#data立即数送直接寻址单元32MOV@Ri,#data立即数送内部RAM单元21MOVdirect,Rn寄存器送直接寻址单元22MOVRn,direct直接寻址单元送寄存器22MOVdirect,@Ri内部RAM单元送直接寻址单元22MOV@Ri,direct直接寻址单元送内部RAM单元22 MOVdirect2,direct1直接寻址单元送直接寻址单元32 MOVDPTR,#data1616位立即数送数据指针32 MOVXA,@Ri外部RAM单元送累加器(8位地址)12 MOVX@Ri,A累加器送外部RAM单元(8位地址)12 MOVXA,@DPTR外部RAM单元送累加器(16位地址)12 MOVX@DPTR,A累加器送外部RAM单元(16位地址)12 MOVCA,@A+DPTR查表数据送累加器(DPTR为基址)12 MOVCA,@A+PC查表数据送累加器(PC为基址)12 XCHA,Rn累加器与寄存器交换11XCHA,@Ri累加器与内部RAM单元交换11XCHDA,direct累加器与直接寻址单元交换21 XCHDA,@Ri累加器与内部RAM单元低4位交换11 SWAPA累加器高4位与低4位交换11POPdirect栈顶弹出指令直接寻址单元22PUSHdirect直接寻址单元压入栈顶22二、算术运算类指令ADDA,Rn累加器加寄存器11ADDA,@Ri累加器加内部RAM单元11ADDA,direct累加器加直接寻址单元21ADDA,#data累加器加立即数21ADDCA,Rn累加器加寄存器和进位标志11ADDCA,@Ri累加器加内部RAM单元和进位标志11 ADDCA,#data累加器加立即数和进位标志21 ADDCA,direct累加器加直接寻址单元和进位标志21 INCA累加器加111INCRn寄存器加111INCdirect直接寻址单元加121INC@Ri内部RAM单元加111INCDPTR数据指针加112DAA十进制调整11SUBBA,Rn累加器减寄存器和进位标志11SUBBA,@Ri累加器减内部RAM单元和进位标志11 SUBBA,#data累加器减立即数和进位标志21 SUBBA,direct累加器减直接寻址单元和进位标志21 DECA累加器减111DECRn寄存器减111DEC@Ri内部RAM单元减111DECdirect直接寻址单元减121MULAB累加器乘寄存器B14DIVAB累加器除以寄存器B14三、逻辑运算类指令ANLA,Rn累加器与寄存器11ANLA,@Ri累加器与内部RAM单元11ANLA,#data累加器与立即数21ANLA,direct累加器与直接寻址单元21 ANLdirect,A直接寻址单元与累加器21 ANLdirect,#data直接寻址单元与立即数31ORLA,Rn累加器或寄存器11ORLA,@Ri累加器或内部RAM单元11 ORLA,#data累加器或立即数21ORLA,direct累加器或直接寻址单元21 ORLdirect,A直接寻址单元或累加器21 ORLdirect,#data直接寻址单元或立即数31 XRLA,Rn累加器异或寄存器11XRLA,@Ri累加器异或内部RAM单元11 XRLA,#data累加器异或立即数21XRLA,direct累加器异或直接寻址单元21 XRLdirect,A直接寻址单元异或累加器21 XRLdirect,#data直接寻址单元异或立即数32 RLA累加器左循环移位11RLCA累加器连进位标志左循环移位11RRA累加器右循环移位11RRCA累加器连进位标志右循环移位11CPLA累加器取反11CLRA累加器清零11四、控制转移类指令类ACCALLaddr112KB范围内绝对调用22AJMPaddr112KB范围内绝对转移22LCALLaddr162KB范围内长调用32LJMPaddr162KB范围内长转移32SJMPrel相对短转移22JMP@A+DPTR相对长转移12RET子程序返回12RET1中断返回12JZrel累加器为零转移22JNZrel累加器非零转移22CJNEA,#data,rel累加器与立即数不等转移32 CJNEA,direct,rel累加器与直接寻址单元不等转移32 CJNERn,#data,rel寄存器与立即数不等转移32CJNE@Ri,#data,relRAM单元与立即数不等转移32 DJNZRn,rel寄存器减1不为零转移22 DJNZdirect,rel直接寻址单元减1不为零转移32 NOP空操作11五、布尔操作类指令MOVC,bit直接寻址位送C21MOVbit,CC送直接寻址位21CLRCC清零11CLRbit直接寻址位清零21CPLCC取反11CPLbit直接寻址位取反21SETBCC置位11SETBbit直接寻址位置位21ANLC,bitC逻辑与直接寻址位22ANLC,/bitC逻辑与直接寻址位的反22ORLC,bitC逻辑或直接寻址位22ORLC,/bitC逻辑或直接寻址位的反22JCrelC为1转移22JNCrelC为零转移22JBbit,rel直接寻址位为1转移32JNBbit,rel直接寻址为0转移1、D1~D8八个彩灯按规定顺序依次点亮(间隔1秒),最后全亮;2、按规定顺序依次熄灭(间隔1秒),最后全灭;3、八个灯同时点亮,保持1秒;4、八个灯同时熄灭,保持0.5秒;再将第3、4步重复4遍,最后整个程序再重复N遍。
(数据传递类指令)MOV A,Rn 寄存器传送到累加器 1 1MOV A,direct 直接地址传送到累加器 2 1 MOV A,@Ri 累加器传送到外部RAM(8) 1 1 MOV A,#data 立即数传送到累加器 2 1MOV Rn,A 累加器传送到寄存器 1 1MOV Rn,direct 直接地址传送到寄存器 2 2 MOV Rn,#data 累加器传送到直接地址 2 1 MOV direct,Rn 寄存器传送到直接地址 2 1 MOV direct,direct 直接地址传送到直接地址 3 2MOV direct,A 累加器传送到直接地址 2 1 MOV direct,@Ri 间接RAM 传送到直接地址 2 2 MOV direct,#data 立即数传送到直接地址 3 2 MOV @Ri,A 直接地址传送到直接地址 1 2 MOV @Ri,direct 直接地址传送到间接RAM 2 1 MOV @Ri,#data 立即数传送到间接RAM 2 2 MOV DPTR,#data16 16 位常数加载到数据指针 3 1MOVC A,@A+DPTR 代码字节传送到累加器 1 2 MOVC A,@A+PC 代码字节传送到累加器 1 2 MOVX A,@Ri 外部RAM(8)传送到累加器 1 2 MOVX A,@DPTR 外部RAM(16)传送到累加器 1 2 MOVX @Ri,A 累加器传送到外部RAM(8) 1 2 MOVX @DPTR,A 累加器传送到外部RAM(16) 1 2 PUSH direct 直接地址压入堆栈 2 2POP direct 直接地址弹出堆栈 2 2XCH A,Rn 寄存器和累加器交换 1 1XCH A, direct 直接地址和累加器交换 2 1XCH A, @Ri 间接RAM 和累加器交换 1 1 XCHD A, @Ri 间接RAM 和累加器交换 1 1低4 位字节(算术运算类指令)INC A 累加器加1 1 1INC Rn 寄存器加1 1 1INC direct 直接地址加1 2 1INC @Ri 间接RAM 加1 1 1INC DPTR 数据指针加1 1 2DEC A 累加器减1 1 1DEC Rn 寄存器减1 1 1DEC direct 直接地址减1 2 2DEC @Ri 间接RAM 减1 1 1MUL AB 累加器和B 寄存器相乘 1 4DIV AB 累加器除以B 寄存器 1 4DA A 累加器十进制调整 1 1ADD A,Rn 寄存器与累加器求和 1 1ADD A,direct 直接地址与累加器求和 2 1ADD A,@Ri 间接RAM 与累加器求和 1 1ADD A,#data 立即数与累加器求和 2 1ADDC A,Rn 寄存器与累加器求和(带进位) 1 1 ADDC A,direct 直接地址与累加器求和(带进位) 2 1ADDC A,@Ri 间接RAM 与累加器求和(带进位) 1 1ADDC A,#data 立即数与累加器求和(带进位) 2 1 SUBB A,Rn 累加器减去寄存器(带借位) 1 1 SUBB A,direct 累加器减去直接地址(带借位) 2 1 SUBB A,@Ri 累加器减去间接RAM(带借位) 1 1 SUBB A,#data 累加器减去立即数(带借位) 2 1 (逻辑运算类指令)ANL A,Rn 寄存器“与”到累加器 1 1ANL A,direct 直接地址“与”到累加器 2 1 ANL A,@Ri 间接RAM“与”到累加器 1 1ANL A,#data 立即数“与”到累加器 2 1ANL direct,A 累加器“与”到直接地址 2 1 ANL direct, #data 立即数“与”到直接地址 3 2 ORL A,Rn 寄存器“或”到累加器 1 2ORL A,direct 直接地址“或”到累加器 2 1 ORL A,@Ri 间接RAM“或”到累加器 1 1ORL A,#data 立即数“或”到累加器 2 1ORL direct,A 累加器“或”到直接地址 2 1 ORL direct, #data 立即数“或”到直接地址 3 1 XRL A,Rn 寄存器“异或”到累加器 1 2XRL A,direct 直接地址“异或”到累加器 2 1 XRL A,@Ri 间接RAM“异或”到累加器 1 1 XRL A,#data 立即数“异或”到累加器 2 1XRL direct,A 累加器“异或”到直接地址 2 1 XRL direct, #data 立即数“异或”到直接地址 31CLR A 累加器清零 1 2CPL A 累加器求反 1 1RL A 累加器循环左移 1 1RLC A 带进位累加器循环左移 1 1RR A 累加器循环右移 1 1RRC A 带进位累加器循环右移 1 1SWAP A 累加器高、低4 位交换 1 1(控制转移类指令)JMP @A+DPTR 相对DPTR 的无条件间接转移 1 2 JZ rel 累加器为0 则转移 2 2JNZ rel 累加器为1 则转移 2 2CJNE A,direct,rel 比较直接地址和累加器,不相等转移 3 2CJNE A,#data,rel 比较立即数和累加器,不相等转移 3 2CJNE Rn,#data,rel 比较寄存器和立即数,不相等转移 2 2CJNE @Ri,#data,rel 比较立即数和间接RAM,不相等转移 3 2DJNZ Rn,rel 寄存器减1,不为0 则转移 3 2 DJNZ direct,rel 直接地址减1,不为0 则转移 3 2 NOP 空操作,用于短暂延时 1 1ACALL add11 绝对调用子程序 2 2LCALL add16 长调用子程序 3 2RET 从子程序返回 1 2RETI 从中断服务子程序返回 1 2AJMP add11 无条件绝对转移 2 2LJMP add16 无条件长转移 3 2SJMP rel 无条件相对转移 2 2(布尔指令)CLR C 清进位位 1 1CLR bit 清直接寻址位 2 1SETB C 置位进位位 1 1SETB bit 置位直接寻址位 2 1CPL C 取反进位位 1 1CPL bit 取反直接寻址位 2 1ANL C,bit 直接寻址位“与”到进位位 2 2 ANL C,/bit 直接寻址位的反码“与”到进位位 2 2ORL C,bit 直接寻址位“或”到进位位 2 2 ORL C,/bit 直接寻址位的反码“或”到进位位 2 2MOV C,bit 直接寻址位传送到进位位 2 1 MOV bit, C 进位位位传送到直接寻址 2 2JC rel 如果进位位为1 则转移 2 2JNC rel 如果进位位为0 则转移 2 2JB bit,rel 如果直接寻址位为1 则转移 3 2 JNB bit,rel 如果直接寻址位为0 则转移 3 2 JBC bit,rel 直接寻址位为1 则转移并清除该位2 2(伪指令)ORG 指明程序的开始位置DB 定义数据表DW 定义16 位的地址表EQU 给一个表达式或一个字符串起名DATA 给一个8 位的内部RAM 起名XDATA 给一个8 位的外部RAM 起名BIT 给一个可位寻址的位单元起名END 指出源程序到此为止(指令中的符号标识)Rn 工作寄存器R0-R7Ri 工作寄存器R0 和R1@Ri 间接寻址的8 位RAM 单元地址(00H-FFH) #data8 8 位常数#data16 16 位常数addr16 16 位目标地址,能转移或调用到64KROM 的任何地方addr11 11 位目标地址,在下条指令的2K 范围内转移或调用Rel 8 位偏移量,用于SJMP 和所有条件转移指令,范围-128~+127Bit 片内RAM 中的可寻址位和SFR 的可寻址位Direct 直接地址,范围片内RAM 单元(00H-7FH)和80H-FFH$ 指本条指令的起始位置结束在讲指令系统前我们先来复习一下数制的概念。
§3.2 数据传送类指令一、本课在教材中的地位与前后知识的联系:本课节选自中国劳动和社会保障出版社《单片机原理及接口技术》第三章第二节“数据传送类指令”,它是在前一节单片机指令常用表示方式和寻址方式的基础上,提出的五大类指令中的第一大类,是单片机所有指令中最重要、也是最常用的一类指令。
它是其他四大类指令的基础,和其他四大类指令共同组成了MCS-51系列单片机的指令系统。
二、对教材的分析与处理:数据传送类指令可以细分为三小种:第一种是数据传送MOV、MOVX、MOVC,第二种是数据交换XCH、XCHD、SWAP,第三种是数据压入弹出PUSH、POP。
在讲解这三种数据传送类的指令时,每一种的这几个指令都可以采用对比的方法来使学生更好理解;另外,每一种的指令都可以列举事例进行讲解,用例子来增强对数据传送类指令的直观感觉。
三、教学目标:1、基础知识目标:(1)掌握数据传送类指令的操作助记符MOV、MOVC、MOVX、XCH、XCHD、SWAP、PUSH、POP。
(2)掌握各数据传送类指令的执行过程。
(3)会用数据传送类指令来书写简单的程序段。
2、能力训练目标:通过对数据传送类指令执行过程的理解,培养学生的想象能力和对比分析能力,提高其运用知识的水平。
3、创新素质目标:在分析和判断数据传送类指令的执行过程中。
培养学生的逻辑推理能力,激发他们的学习兴趣,增强学生对未知事物的探索欲。
四、教学过程和方法:本节课采用传统的教学过程:先复习巩固上一节MCS-51系列单片机指令的格式和寻址方式,由此引出本节所讲的第一条指令、也是最重要的一条指令MOV;然后逐次讲解MOVX、MOVC、XCH、XCHD、SWAP、PUSH、POP等数据传送类指令,并以例题的方式加深学生对这几条指令的理解。
为了让学生更好的掌握数据传送类指令,充分利用对比分析(把MOV、MOVC、MOVX进行对比,把XCH、XCHD、SWAP进行对比,把PUSH、POP进行对比)方法,使学生在比较中加深记忆,更快的掌握这几个指令。
51单片机指令表汇总51单片机是一种广泛应用的微控制器,其指令集是进行编程的基础。
下面将51单片机的指令表进行汇总,以帮助初学者更好地理解其指令集。
一、数据传输指令1、MOV指令:将源操作数的内容传送到目标操作数。
2、XCH指令:将两个操作数的内容互换。
3、MOVC指令:从外部存储器将数据传送到目标操作数。
4、MOVX指令:将外部存储器中的数据传送到目标操作数。
5、PUSH指令:将数据压入堆栈。
6、POP指令:从堆栈中弹出数据。
二、算术运算指令1、ADD指令:将两个操作数相加,并将结果存放在目标操作数中。
2、SUB指令:从目标操作数中减去源操作数,并将结果存放在目标操作数中。
3、MUL指令:将两个操作数相乘,并将结果存放在目标操作数中。
4、DIV指令:将目标操作数除以源操作数,并将结果存放在目标操作数中。
5、ANL指令:对目标操作数和源操作数进行按位与运算,并将结果存放在目标操作数中。
6、ORL指令:对目标操作数和源操作数进行按位或运算,并将结果存放在目标操作数中。
7、XRL指令:对目标操作数和源操作数进行按位异或运算,并将结果存放在目标操作数中。
8、CPL指令:对目标操作数进行按位取反运算,并将结果存放在目标操作数中。
9、INC指令:将目标操作数加1。
10、DEC指令:将目标操作数减1。
11、ASR指令:将目标操作数右移n位,最高位用符号位补齐。
12、LSR指令:将目标操作数右移n位,最低位用0补齐。
13、ROL指令:将目标操作数循环左移n位,最高位移入最低位。
14、ROR指令:将目标操作数循环右移n位,最低位移入最高位。
单片机汇编指令表一、概述在单片机的世界里,汇编语言扮演着举足轻重的角色。
它是一种低级语言,能够直接与硬件进行交互,提供高效的代码执行效率。
下面,我们将详细列出一些常见的单片机汇编指令,以及它们的功能。
二、指令表1、MOV指令:用于将数据从一个寄存器移动到另一个寄存器。
例如,MOV R1, R2将把 R2的内容移动到 R1中。
单片机的累加器A与片外RAM之间的数据传递类指令
MOVX A,@Ri
MOVX @Ri,A
MOVX A,@DPTR
MOVX @DPTR,A
说明:
1)在51系列单片机中,与外部存储器RAM打交道的只能是A累加器。
所有需要传送入外部RAM的数据必需要通过A送去,而所有要读入的外部RAM中的数据也必需通过A读入。
在此我们能看出内外部RAM的区别了,内部RAM间能直接进行数据的传递,而外部则不行,比如,要将外部RAM中某一单元(设为0100H单元的数据)送入另一个单元(设为0200H单元),也必须先将0100H 单元中的内容读入A,然后再传送到0200H单元中去。
要读或写外部的RAM,当然也必须要知道RAM的地址,在后两条单片机指令中,地址是被直接放在DPTR中的。
而前两条指令,由于Ri(即R0或R1)只是一个8位的寄存器,所以只供给低8位地址。
因为有时扩展的外部RAM的数量比较少,少于或等于256个,就只需要供给8位地址就够了。
使用时应当首先将要读或写的地址送入DPTR或Ri中,然后再用读写命令。
例:将单片机外部RAM中100H单元中的内容送入外部RAM中200H单元中。
MOV DPTR,#0100H
MOVX A,@DPTR
MOV DPTR,#0200H
MOVX @DPTR,A
程序存储器向累加器A传送指令
MOVC A,@A+DPTR 本指令是将ROM中的数送入A中。
本指令也被称为单片机查表指令,常用此指令来查一个已做好在ROM中的表格说明:
此条指令引出一个新的寻址办法:变址寻址。
本指令是要在ROM的一个地址单元中找出数据,显然必须知道这个单元的地址,这个单元的地址是这样确定的:在执行本指令立脚点DPTR中有一个数,A中有一个数,执行指令时,将A和DPTR中的数加起为,就成为要查找的单元的地址。
查找到的结果被放在A中,因此,本条指令执行前后,A中的值不一定相同。
例:有一个数在R0中,要求用查表的办法确定它的平方值(此数的取值范围是0-5)
MOV DPTR,#TABLE
MOV A,R0
MOVC A,@A+DPTR
TABLE: DB 0,1,4,9,16,25
设R0中的值为2,送入A中,而DPTR中的值则为TABLE,则最终确定的ROM 单元的地址就是TABLE+2,也就是到这个单元中去取数,取到的是4,显然它正是2的平方。
其它数据也能类推。
标号的真实含义:从这个地方也能看到另一个问题,我们使用了标号来替代具体的单元地址。
事实上,标号的真实含义就是地址数值。
在这里它代表了,0,1,4,9,16,25这几个数据在ROM中存放的起点位置。
而在以前我们学过的如LCALL DELAY单片机指令中,DELAY 则代表了以DELAY为标号的那段程序
在ROM中存放的起始地址。
事实上,CPU正是通过这个地址才找到这段程序的。
能通过以下的例程再来看一看标号的含义:
MOV DPTR,#100H
MOV A,R0
MOVC A,@A+DPTR
ORG 0100H.
DB 0,1,4,9,16,25
如果R0中的值为2,则最终地址为100H+2为102H,到102H单元中找到的是4。
这个能看懂了吧?
那为什么不这样写程序,要用标号呢?不是增加疑惑吗?
如果这样写程序的话,在写程序时,我们就必须确定这张表格在ROM中的具体的位置,如果写完程序后,又想在这段程序前插入一段程序,那么这张表格的位置就又要变了,要改ORG 100H这句话了,我们是经常需要修改程序的,那多麻烦,所以就用标号来替代,只要一编译程序,位置就自动发生变化,我们把这个麻烦事交给计算机��指我们用的电脑去做了。
堆栈操作
PUSH direct
POP direct
第一条指令称之为推入,就是将direct中的内容送入堆栈中,第二条指令称之为弹出,就是将堆栈中的内容送回到direct中。
推入指令的执行过程是,首先将SP中的值加1,然后把SP中的值当作地址,将direct中的值送进以SP中的值
为地址的RAM单元中。
例:
MOV SP,#5FH
MOV A,#100
MOV B,#20
PUSH ACC
PUSH B
则执行第一条PUSH ACC指令是这样的:将SP中的值加1,即变为60H,然后将A中的值送到60H单元中,因此执行完本条指令后,内存60H单元的值就是100,同样,执行PUSH B时,是将SP+1,即变为61H,然后将B中的值送入到61H单元中,即执行完本条指令后,61H单元中的值变为20。
POP指令的在单片机中执行是这样的,首先将SP中的值作为地址,并将此地址中的数送到POP指令后面的那个direct中,然后SP减1。
接上例:
POP B
POP ACC
则执行过程是:将SP中的值(现在是61H)作为地址,取61H单元中的数值(现在是20),送到B中,所以执行完本条指令后B中的值是20,然后将SP减1,因此本条指令执行完后,SP的值变为60H,然后执行POP ACC,将SP中的值(60H)作为地址,从该地址中取数(现在是100),并送到ACC中,所以执行完本条指令后,ACC中的值是100。
这有什么意义呢?ACC中的值本来就是100,B中的值本来就是20,是的,在本例中,的确没有意义,但在实际工作中,则在PUSH B后一般要执行其他指令,
而且这些指令会把A中的值,B中的值改掉,所以在程序的结束,如果我们要把A和B中的值恢复原值,那么这些指令就有意义了。
还有一个问题,如果我不用堆栈,比如说在PUSH ACC指令处用MOV 60H,A,在PUSH B处用指令MOV 61H,B,然后用MOV A,60H,MOV B,61H来替代两条POP指令,不是也一样吗?是的,从结果上看是一样的,但是从过程看是不一样的,PUSH和POP指令都是单字节,单周期指令,而MOV指令则是双字节,双周期指令。
更何况,堆栈的作用不止于此,所以一般的计算机上都设有堆栈,单片机也是一样,而我们在编写子程序,需要保存数据时,常常也不采用后面的办法,而是用堆栈的办法来实现。
例:写出以下单片机程序的运行结果
MOV 30H,#12
MOV 31H,#23
PUSH 30H
PUSH 31H
POP 30H
POP 31H
结果是30H中的值变为23,而31H中的值则变为12。
也就两者进行了数据交换。
从这个例程能看出:使用堆栈时,入栈的书写次序和出栈的书写次序必须相反,才能保证数据被送回原位,不然就要出错了。
作业:在MCS51下执行上面的例程,注意观察内存窗口和堆栈窗口的变化。