列举吴亦凡四种语言常用的汇编语言设计结构

推荐这篇日记的豆列
······面向机器的编程语言 : 汇编语言:如果自己要发明一种编程语言,那么需要做些什么事情呢? - 推酷
面向机器的编程语言 : 汇编语言:如果自己要发明一种编程语言,那么需要做些什么事情呢?
面向机器的编程语言 : 汇编语言:如果自己要发明一种编程语言,那么需要做些什么事情呢?
先要完成对于一门编程语言的各个要素:比如定义你自己的语法、数据类型、语言结构等等,其次你要写一个支持这些语法的解释器或编译器。 就我的理解,当你编写完成一个编译器或解释器,基本上你的代码就可以用了。
汇编语言是从机器语言转换过来的.最早的计算机系统没有可用的高级语言,是直接用0101这样的二进制编码来编程的,这样对绝大多数用户就很不方便,因为这要求对计算机系统的软件和硬件资源要非常了解才可以.记忆量也很大.到后来,大家就用一些符号来代替一些二进制代码,方便识别,比如原来代码1011意思是加法,现在就不写1011了,写成ADD,用ADD这个大家都容易识别的符号来编程,可以提升一些效率.但计算机的执行仍然只识别二进制代码,所以需要把汇编语言写的代码再转换成机器语言.
汇编语言是一种低级语言,好处是可以直接控制计算机的软硬件资源.坏处就是对编程人员的要求非常高.计算机执行的时候,用汇编语言编写的代码的执行效率是最高的.和机器语言代码的效率一样高.
1.面向机器的程序设计语言
汇编语言(Assembly Language)是面向机器的程序设计语言。在汇编语言中,用助记符(Memoni)代替机器指令的操作码,用地址符号(Symbol)或标号(Label)代替指令或操作数的地址,如此就增强了程序的可读性和编写难度,象这样符号化的程序设计语言就是汇编语言,因此亦称为符号语言。使用汇编语言编写的程序,机器不能直接识别,还要由汇编程序或者叫汇编语言编译器转换成机器指令。汇编程序将符号化的操作代码组装成处理器可以识别的机器指令,这个组装的过程称为组合或者汇编。因此,有时候人们也把汇编语言称为组合语言。
汇编语言是直接面向处理器(Processor)的程序设计语言。处理器是在指令的控制下工作的,处理器可以识别的每一条指令称为机器指令。每一种处理器都有自己可以识别的一整套指令,称为指令集。处理器执行指令时,根据不同的指令采取不同的动作,完成不同的功能,既可以改变自己内部的工作状态,也能控制其它外围电路的工作状态。
如图所示,在电路中,每条机器指令都表现为一组电信号,通过一排导线进入处理器。这些电信号有的呈高电平,有的呈低电平,哪些为高,哪些为低,取决于不同的机器指令。如果把高电平记为“1”,低电平记为“0”,那么,不同的机器指令将表现为不同的二进制序列,由于它们的无规律性,这就使得机器指令机器指令难以理解、书写和记忆。
人类最容易接受自己每天都使用的自然语言。为了使机器指令的书写和理解变得容易,需要借鉴自然语言的优点,为此就引入了汇编语言。汇编语言使用符号来代表不同的机器指令,而这些符号非常接近于自然语言的要素。基本上,汇编语言里的每一条指令,都对应着处理器的一条机器指令。
汇编语言包括两个部分:语法部分和编译器。语法部分提供与机器指令相对应的助记符,方便指令的书写和阅读。当然,汇编语言的符号可以被人类接受,但不能被处理器识别,为此,还要由汇编语言编译器将这些助记符转换成机器指令。
根据应用领域的不同,处理器的种类繁多,比如用于工业控制和嵌入式计算的Z80、MC68000和MCS-51、广泛应用于个人计算机的INTELx86系列,以及基于ARM体系结构的处理器,包括苹果公司在内的大企业都是ARM的客户。事实上,今天的ARM是最受欢迎的32位嵌入式处理器,而且,今天的ARM处理器比INTEL奔腾系列卖得还多,基本上是3:1的比例。
不同的处理器有不同的指令集。正是因为这个原因,每一种处理器都会有自己专属的汇编语言语法规则和编译器。即使是同一种类型的处理器,也可能拥有不同的汇编语言编译器。一个明显的例子是INTEL x86系列的处理器,围绕它就开发出好多种编译器来,如MASM、NASM、FASM、TASM和AT&T等。而且,这每一种编译器,都使用不同的语法。
1、因为用汇编语言设计的程序最终被转换成机器指令,故能够保持机器语言的一致性,直接、简捷,并能象机器指令一样访问、控制计算机的各种硬件设备,如磁盘、存储器、CPU、I/O端口等。使用汇编语言,可以访问所有能够被访问的软、硬件资源。
2、目标代码简短,占用内存少,执行速度快,是高效的程序设计语言,经常与高级语言配合使用,以改善程序的执行速度和效率,弥补高级语言在硬件控制方面的不足,应用十分广泛。
1、汇编语言是面向机器的,处于整个计算机语言层次结构的底层,故被视为一种低级语言,通常是为特定的计算机或系列计算机专门设计的。因此,不同的处理器有不同的汇编语言语法和编译器,编译的程序无法在不同的处理器上执行,缺乏可移植性;
2、难于从汇编语言代码上理解程序设计意图,可维护性差,即使是完成简单的工作也需要大量的汇编语言代码,很容易产生bug,难于调试;
3、使用汇编语言必须对某种处理器非常了解,而且只能针对特定的体系结构和处理器进行优化,开发效率很低,周期长且单调。
历史上,汇编语言曾经是非常流行的程序设计语言之一。随着软件规模的增长,以及随之而来的对软件开发进度和效率的要求,高级语言逐渐取代了汇编语言。但即便如此,高级语言也不可能完全替代汇编语言的作用。就拿Linux内核来讲,虽然绝大部分代码是用C语言编写的,但仍然不可避免地在某些关键地方使用了汇编代码。由于这部分代码与硬件的关系非常密切,即使是C语言也会显得力不从心,而汇编语言则能够很好扬长避短,最大限度地发挥硬件的性能。
首先,汇编语言的大部分语句直接对应着机器指令,执行速度快,效率高,代码体积小,在那些存储器容量有限,但需要快速和实时响应的场合比较有用,比如仪器仪表和工业控制设备中。
其次,在系统程序的核心部分,以及与系统硬件频繁打交道的部分,可以使用汇编语言。比如操作系统的核心程序段、I/O接口电路的初始化程序、外部设备的低层驱动程序,以及频繁调用的子程序、动态连接库、某些高级绘图程序、视频游戏程序等等。
再次,汇编语言可以用于软件的加密和解密、计算机病毒的分析和防治,以及程序的调试和错误分析等各个方面。
最后,通过学习汇编语言,能够加深对计算机原理和操作系统等课程的理解。通过学习和使用汇编语言,能够感知、体会和理解机器的逻辑功能,向上为理解各种软件系统的原理,打下技术理论基础;向下为掌握硬件系统的原理,打下实践应用基础。
1.机器相关性。
这是一种面向机器的低级语言,通常是为特定的计算机或系列计算机专门设计的。因为是机器指令的符号化表示,故不同的机器就有不同的汇编语言。使用汇编语言能面向机器并较好地发挥机器的特性,得到质量较高的程序。
2.高速度和高效率。
汇编语言保持了机器语言的优点,具有直接和简捷的特点,可有效地访问、控制计算机的各种硬件设备,如磁盘、存储器、CPU、I/O端口等,且占用内存少,执行速度快,是高效的程序设计语言。
3.编写和调试的复杂性。
由于是直接控制硬件,且简单的任务也需要很多汇编语言语句,因此在进行程序设计时必须面面俱到,需要考虑到一切可能的问题,合理调配和使用各种软、硬件资源。这样,就不可避免地加重了程序员的负担。与此相同,在程序调试时,一旦程序的运行出了问题,就很难发现。
x86处理器指令集
数据传送指令
这部分指令包括通用数据传送指令MOV、条件传送指令CMOVcc、堆栈操作指令PUSH/PUSHA/PUSHAD/POP/POPA/POPAD、交换指令XCHG/XLAT/BSWAP、地址或段描述符选择子传送指令LEA/LDS/LES/LFS/LGS/LSS等。注意,CMOVcc不是一条具体的指令,而是一个指令簇,包括大量的指令,用于根据EFLAGS寄存器的某些位状态来决定是否执行指定的传送操作。
整数和逻辑运算指令
这部分指令用于执行算术和逻辑运算,包括加法指令ADD/ADC、减法指令SUB/SBB、加一指令INC、减一指令DEC、比较操作指令CMP、乘法指令MUL/IMUL、除法指令DIV/IDIV、符号扩展指令CBW/CWDE/CDQE、十进制调整指令DAA/DAS/AAA/AAS、逻辑运算指令NOT/AND/OR/XOR/TEST等。
这部分指令用于将寄存器或内存操作数移动指定的次数。包括逻辑左移指令SHL、逻辑右移指令SHR、算术左移指令SAL、算术右移指令SAR、循环左移指令ROL、循环右移指令ROR等。
位操作指令
这部分指令包括位测试指令BT、位测试并置位指令BTS、位测试并复位指令BTR、位测试并取反指令BTC、位向前扫描指令BSF、位向后扫描指令BSR等。
条件设置指令
这不是一条具体的指令,而是一个指令簇,包括大约30条指令,用于根据EFLAGS寄存器的某些位状态来设置一个8位的寄存器或者内存操作数。比如SETE/SETNE/SETGE等等。
控制转移指令
这部分包括无条件转移指令JMP、条件转移指令Jcc/JCXZ、循环指令LOOP/LOOPE/LOOPNE、过程调用指令CALL、子过程返回指令RET、中断指令INTn、INT3、INTO、IRET等。注意,Jcc是一个指令簇,包含了很多指令,用于根据EFLAGS寄存器的某些位状态来决定是否转移;INT n是软中断指令,n可以是0到255之间的数,用于指示中断向量号。
串操作指令
这部分指令用于对数据串进行操作,包括串传送指令MOVS、串比较指令CMPS、串扫描指令SCANS、串加载指令LODS、串保存指令STOS,这些指令可以有选择地使用REP/REPE/REPZ/REPNE和REPNZ的前缀以连续操作。
输入输出指令
这部分指令用于同外围设备交换数据。包括端口输入指令IN/INS、端口输出指令OUT/OUTS。
高级语言辅助指令
这部分指令为高级语言的编译器提供方便。包括创建栈帧的指令ENTER和释放栈帧的指令LEAVE。
控制和特权指令
这部分包括无操作指令NOP、停机指令HLT、等待指令WAIT/MWAIT、换码指令ESC、总线封锁指令LOCK、内存范围检查指令BOUND、全局描述符表操作指令LGDT/SGDT、中断描述符表操作指令LIDT/SIDT、局部描述符表操作指令LLDT/SLDT、描述符段界限值加载指令LSR、描述符访问权读取指令LAR、任务寄存器操作指令LTR/STR、请求特权级调整指令ARPL、任务切换标志清零指令CLTS、控制寄存器和调试寄存器数据传送指令MOV、高速缓存控制指令INVD/WBINVD/INVLPG、型号相关寄存器读取和写入指令RDMSR/WRMSR、处理器信息获取指令CPUID、时间戳读取指令RDTSC等。
浮点和多媒体指令
这部分指令用于加速浮点数据的运算,以及用于加速多媒体数据处理的单指令多数据(SIMD及其扩展SSEx)指令。这部分指令数据非常庞大,无法一一列举,请自行参考INTEL手册。
虚拟机扩展指令
这部分指令包括INVEPT/INVVPID/VMCALL/VMCLEAR/VMLAUNCH/VMRESUME/VMPTRLD/VMPTRST/VMREAD/VMWRITE/VMXOFF/VMON等。
对于一个全面了解微机原理的程序员,汇编语言是必修语言。
已发表评论数()
已收藏到推刊!
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
排版有问题
没有分页内容
视频无法显示
图片无法显示汇编语言程序设计_单片机原理与接口技术(郭文川)_ppt_大学课件预览_高等教育资讯网
单片机原理与接口技术(郭文川):第四章
汇编语言程序设计
分类: 格式: 日期:日
第 4章 汇编语言程序设计4.1 汇编语言程序设计方法4.2 汇编语言源程序的基本结构顺序、循环、分支、子程序4.3 常用程序设计举例4.1.1 MCS-51汇编语言伪指令伪指令不属于指令系统,汇编后不会产生机器码,只用来对汇编过程进行控制或提供某些汇编信息 。如:规定汇编生成的目标代码在内存种的存放区域,给源程序中的符号和标号赋值以及指示汇编的结束等 。但它不会令计算机做任何操作,没有对应的机器语言代码,由于它有指令的形式而无指令的实质,所以称,伪,指令 。4.1 汇编语言程序设计方法4.1.3 MCS-51汇编语言伪指令1,ORG( Origin) 汇编起始地址命令功能:用于规定目标程序的起始地址 。格式:[标号,] ORG 地址地址项,16位绝对地址,也可以用标号或表达式表示 。如果不用 ORG规定,则汇编得到的目标程序将从 0000H开始 。一个源程序中,可多次使用 ORG指令以规定不同程序段的起始位置。地址应从小到大顺序排列,不允许重叠。例如,ORG 0000HLJMP MAINORG 4200HMAIN,MOV A,30H2,DB( Define Byte) 字节定义伪指令功能:用于从指定的地址单元开始,在程序存储器中定义字节数据 。格式,[标号,] DB 8位数表例如,DB,how are you?”常使用本命令存放数据表格,例如存放数码管显示的十六进制数的字形码,可使用多条 DB命令定义:DB C0H,F9H,A4H,B0HDB 99H,92H,82H,F8HDB 80H,90H,88H,83HDB C6H,A1H,86H,84H3,DW( Define Word) 字定义伪指令功能:用于从指定地址开始,在程序存储器单元中定义 16位的数据字 。格式,[标号,] DW 16位数表存放规则:高 8位在前 ( 低地址 ),低 8位在后 ( 高地址 ) 。例:DW 100H,1ACH,-814 ;按顺序存 01H,00H,01H,ACH,D2H,FCHDW,AA” ;存入 41H,41HDW,A” ;存入 00H,41HDW,ABC” ;不合法,因是两个字节查表时,为确定数据区的起始位置,可采用两种方法:( 1) 根据 DB命令前一条指令的地址确定 。例,8100H MOV A,#49H ( 1字节 )TAB,DB C0H,F9H,A4H,B0H( 2) 使用 ORG指令专门规定例,ORG 8100HTAB,DB C0H,F9H,A4H,B0H定义的数码管字形码从 8100地址开始存放 。注意,DB和 DW定义的数表,数的个数不得超过 80个。如果数据的数目较多时,可使用多个定义命令。在 MCS-51程序设计应用中,常以 DB定义数据,以 DW定义地址。4,DS( Define Storage) 定义存储区伪指令功能:用于从指定地址开始,保留指定数目的字节单元为存储区,供程序运行使用 。 汇编时对这些单元不赋值 。格式,[标号,] DS 16位数表例,ADDRTABL,DS 20例,ORG 8100HDS 08H注意:对 MSC-51单片机来说,DB,DW,DS命令只能对程序存储器使用,不能对数据存储器使用 。5,EQU( Equate) 赋值伪指令功能:用于给字符名称赋予一个特定值 。 赋值以后,其值在整个过程中有效 。格式:字符名称 EQU 赋值项,赋值项,,可以是常数,地址,标号或表达式 。8位或 16位二进制数 。 赋值以后的字符名称即可作地址使用,也可作立即数使用 。PA8155 EQU 8001H给标号 PA8155赋值 8001H。6,BIT 定义位地址符号伪指令功能,用于给字符名称赋以位地址 。格式,字符名称 BIT 位地址例如:AAA BIT 40HBBB BIT 50H其中,位地址,可以是绝对地址,也可以是符号地址 。7,END( END of assembly) 汇编终止命令功能:用于终止源程序的汇编工作。END之后的指令,汇编程序不予处理。格式:[标号,] END [表达式 ]只有主程序模块才有,表达式,项,且,表达式,的值等于该程序模块的入口地址 。 而其他程序模块就没有,表达式,项。,标号:,也是选择项 。一个源程序只能有一个 END命令 。4.1.2 程序的设计步骤与方法汇编和高级语言程序设计的过程:首先对问题进行分析,然后确定算法,再根据算法流程编写程序,最后是调试程序 。汇编语言程序设计的 独特点 在于:( 1) 用汇编语言进行程序设计时,对 数据的存放,寄存器和工作单元的使用等要由设计者安排 。 而高级语言程序设计时,这些工作都由计算机软件安排,程序设计者不必考虑 。( 2) 汇编语言程序设计要求设计人员必须对所使用的计算机的硬件结构有较为详细的了解 。特别是对 各类寄存器、端口、定时器 /计数器、中断等 内容要熟悉,以便在程序设计时能熟练使用。汇编语言程序的设计步骤:( 1)分析问题,抽象出描述问题的数学模型( 2)确定解决问题的算法( 3)根据算法绘制流程图( 4)分配存储空间及工作单元( 5)编写源程序( 6)上机调试程序质量的判断标准:程序的执行时间短;占用的内存单元少;程序的语句行数少。4.1.3 汇编语言源程序的编辑和汇编1,汇编语言源程序的编辑编辑好的源程序应以,,ASM”扩展名存盘2,汇编语言源程序的汇编源程序经机器汇编之后,若无语法错误,一般将生成两个新文件,它们的扩展名分别是,OBJ和,LST。例 4-1 将内部 RAM从 30H开始的 10个单元的内容相加,其和保存于 A(假设其和仍为 8位数)。列表文件(,LST)信息如下:地址 机器码 汇编语言源程序 注释ORG 2000H ;定义程序起始地址 START,MOV R0,#30H ;初始地址送 R0A MOV R2,#10 ;循环初始值送 R2 MOV A,#00H ;累加和初始值送 A2006 26 LOOP,ADDC A,@R0 ;完成累加2007 08 INC R0 ;修改地址2008 DAFC DJNZ R2,LOOP ;循环判断200A 80FE SJMP $ ;暂停END ;程序结束C INCLUDE IN HASHTABC START,2000C LOOP,2006目标文件(,OBJ)信息如下:07A0ADAFC80FE方法一:用逻辑指令将高,低半字节分开,对数字 0~9加上 30H即可得到所对应的 ASCII码 30H~39H。ORG 2000HMOV A,40H ;取数ANL A,#0FH ;分离出低半字节ADD A,#30H ;变为 ASCII码MOV 42H,A ;保存MOV A,40H ;重新取数SWAP A ;高、低半字节交换ANL A,#0FH ;分离出高半字节ADD A,#30H ;变为 ASCII码MOV 41H,A ;保存END例 4-2 将 40H单元的高、低半字节的两个 BCD码拆开并变成其 ASCII码,并分别存入 41H和 42H单元汇编语言程序共有四种结构形式:顺序结构、循环结构、分支结构和子程序结构。方法二:采用 BCD数除以 10H的方法,可把处于高、低半字节的两个 BCD码分别移到 A和 B的低 4位,然后再各自与 30H相“或”即变为 ASCII码。参考程序如下:ORG 2000HMOV A,40H ;取数MOV B,#10H ;送被除数DIV AB ;分离高、低半字节ORL B,#30H ;低 4位调整为 ASCII码MOV 42H,BORL A,#30H ;高 4位调整为 ASCII码MOV 41H,AEND例 4-2 将 40H单元的高、低半字节的两个 BCD码拆开并变成其 ASCII码,并分别存入 41H和 42H单元例 求两个 8位无符号数的和 。设两个 8位无符号数分别存放在内部 RAM 20H和 21H单元,所求和 ( 不超过 255) 存放在 22H单元 。ORG 2000HSTART,MOV R0,#20HMOV A,@R0INC R0ADD A,@R0INC R0MOV @R0,ASJMP $END4.2.5 循环程序设计循环初态循环程序一般由四个主要部分组成,(1) 初始化部分,为循环程序做准备,如规定循环次数,给各变量和地址指针预置初值 。(2) 处理部分,为反复执行的程序段,是循环程序的实体,也是循环程序的主体 。(3) 循环控制部分,这部分的作用是修改循环变量和控制变量,并判断循环是否结束,直到符合结束条件时,跳出循环为止 。(4) 结束部分,这部分主要是对循环程序的结果进行分析、处理和存放。循环:单重循环多重循环 ( 二重以上 ) --循环嵌套 。在多重循环程序中,只允许外重循环嵌套内重循环程序,而不允许循环体互相交叉,另外,也不允许从循环程序的外部跳入循环程序的内部 。例 4-3 把外部 RAM 5000H~50FFH单元的内容清零 。ORG 2000HSTART1,MOV DPTR,#5000H ;循环初始化MOV R0,#00HMOV A,#00HLOOP1,MOVX @DPTR,A ;循环体INC DPTRINC R0CJNE R0,#00H,LOOP1;循环控制END例 4-4 将内部 RAM从 40H开始连续单元的数据传送到外部 RAM从 2000H开始的连续单元中,当所传送的数据为 0FFH时,传送停止。解:ORG 2000HMOV R0,#40H ;循环初始化MOV DPTR,#2000HLOOP,MOV A,@R0CJNE A,#0FFH,LOOP1 ;循环控制SJMP NEXTLOOP1:MOVX @DPTR,A ;循环体INC R0INC DPTRSJMP LOOPNEXT,SJMP $END例 4-5 从 P1口重复 256次读数并取平均值,平均值的整数和小数部分分别保存于内部 RAM的 30H和 31H单元中。解:假设将 R2 R3作为 16位寄存器以保存连续 256次读数的累加和ORG 4000HINTEGER EQU 30HDECIMAL EQU 31HAVR,MOV R2,#0 ;循环初始化MOV R3,#0MOV R4,#0 ;累加次数为 256AVR1,MOV A,P1 ;循环体ADD A,R3 ;累加至低 8位JNC AVR2 ;无进位则暂存结果INC R2 ;有进位则高 8位加增 1AVR2,MOV R3,A ;暂存低 8位DJNZ R4,AVR1 ;循环控制MOV INTEGER,R2MOV DECIMAL,R3END例 设单片机外部数据存储器起始地址为 3000H的数据块中有100个补码,要求逐一检查,若为负数则求补后放回,正数则不变 。 ORG 1000HSTART1,MOV R7,#64H ;设置循环初始值MOV DPTR,#3000HLOOP1,MOVX A,@DPTRJNB ACC.7,LOOP2CPL AINC AMOVX @DPTR,ALOOP2,INC DPTR ;外部 RAM单元加 1DJNZ R7,LOOP1END例 有 10个无符号数依次存放在内部 RAM 30H开始的单元中,求其和,并将结果放在 R2和 R3中 。ORG 2000HMOV R0,#30HMOV R2,#00HMOV R3,#00HMOV R7,#0AHNEXT,MOV A,@R0 ;设置循环初始值ADD A,R3MOV R3,AMOV A,R2ADDC A,#00HMOV R2,AINC R0DJNZ R7,NEXTSJMP $END例 4.6 设 MCS-51单片机的时钟频率为 fosc = 12 MHz,试设计延时 50ms的延时程序 。延时程序所花费的时间是该程序指令的总机器周期数与机器周期的乘积 。通常,延时程序采用 MOV和 DJNZ指令来实现 。单循环延时程序,最大的循环次数位 256,则程序段为:MOV R0,#00H ;机器周期数为 1DJNZ R0,$ ;机器周期数为 2若单片机晶振为 12MHz,则一个机器周期为 1us。延时时间:( 1+256× 2) × 1μ s= 513μ s。需采用多重循环。多重循环,在一个循环体中又包含了其它的循环程序 。这种方式是实现延时程序的常用方法 。 使用多重循环时,必须 注意,(1) 循环嵌套,必须层次分明,不允许产生内外层循环交叉 。(2) 外循环可以一层层向内循环进入,结束时由里往外一层层退出 。(3) 内循环可以直接转入外循环,实现一个循环由多个条件控制的循环结构方式 。MOV R1,#MLOOP,MOV R2,#NNOPDJNZ R2,$DJNZ R1,LOOP内层循环的机器周期数为 Tn=1+1+2*N,总机器周期数为 Tm=( Tn+2)*M+1.设 N=123,M=200,则延时时间为 50.001ms。修改后程序清单:ORG 2000HMOV R1,#0C8H(200)LOOP,MOV R2,#7BH(123)NOPDJNZ R2,$DJNZ R1,LOOPSJMP $END补充例 设三字节无符号数相加被加数:内部 RAM 22H~ 20H单元 ( 低位在低字节 ),加数,内部 RAM 32H~ 30H单元 ( 低位在低字节 ),结果:存于内部 RAM 22H~ 20H单元,进位位存于 23H单元 。利用 ADDC指令进行多字节加法运算 。ORG 4200HMOV R0,#20H ;被加数的低字节地址MOV R1,#30H ;加数的低字节地址MOV R2,#03H ;循环次数CLR CLOOP,MOV A,@R0ADDC A,@R1 ;低字节相加MOV @R0,A ;存放字节相加结果INC R0INC R1DJNZ R2,LOOP ;循环控制MOV A,#00HADDC A,#00HMOV @R0,A ;进位位送 23HEND4.2.3 分支程序分支程序的基本结构:单分支和多分支 。其特点是:各处理模块是相互排斥的 。13条条件转移指令,分别为,JZ,JNZ,累加器判零转移指令;CJNE,比较条件转移指令;DJNZ,减 1条件转移指令 ;JC,JNC,JB,JNB,JBC,位控制条件转移指令等四类。(1)单重分支结构例 4-7 片内 RAM DATA1和 DATA2两个单元中各存有一个无符号数字,将两个数中的小者存入 MIN单元 。ORG 4000HMIN EQU 30HDATA1 EQU 31HDATA2 EQU 32HMOV A,DATA1 ;第一数送 ACLR CCJNE A,DATA2,UNEQU ;两数比较SJMP STORE ;相等,DATA1作为小的数UNEQU,JC STORE ;有借位,DATA1为小MOV A,DATA2 ;无借位,DATA2为小STORE,MOV MIN,A ;小者送 RAMEND例 4-8 片内 RAM两个单元中存有不相等的有符号数字 X和 Y,比较两数的大小,并将大数存入 MAX单元。若 X-Y> 0,则当( OV)= 0时,X> Y;当( OV)= 1时,X< Y;若 X-Y< 0,则当( OV)= 0时,X< Y;当( OV)= 1时,X> Y。图 4-6 例 4-8的流程图X 送 MAXX = Y?Y分支 0N( X - Y ) & 0?YOV = 1?NOV = 1?Y 送 MAXNNYY例 4-8 片内 RAM两个单元中存有不相等的有符号数字 X和 Y,比较两数的大小,并将大数存入 MAX单元。ORG 1000HXD EQU 31HYD EQU 32HMAX EQU 30HCLR CMOV A,XDSUBB A,YD ; X-Y,形成 OV标志JZ XMAX ;若 X=Y,则转向 FINISHJB ACC.7,NEG ;若 (X-Y)&0,则转向 NEGJB OV,YMAX ;若 (OV)=1,则转向 YMAXSJMP XMAX ;若 (OV)=0,则转向 XMAXNEG,JB OV,XMAX ;若 (OV)=1,则转向 XMAXYMAX,MOV A,YD ; Y&X,存 YSJMP FINISHXMAX,MOV A,XD ; X&Y,存 XFINISH,MOV MAX,A ;大数送 MAX单元END( 2)多重分支结构例 设 x,y分别存放在内部 RAM 30H和 40H中,根据 x的值,给 y赋值为 01H,00H,0FFH(-1).011y000xxxORG 2000HMOV A,30HJZ DONEJB ACC.7,LOOPMOV A,#01HSJMP DONELOOP,MOV A,#0FFHDONE,MOV 40H,ASJMP $END(3)散转结构例 设 R7的内容为 0~ n,对应的处理程序入口地址分别为PROG0~PROGn,编写散转程序 。跳转方法:逐个比较,类似 CASE。使用散转指令 JMP @A+DPTR 。设( R7)= 0~ n,对应的处理程序入口地址分别为PROG0~PROGn,且按照一定的规律排列 。ORG 2000HMOV DPTR,#TAB ;设置处理程序入口首地址MOV A,R7CLR CRLC A ;JNC NEXTINC DPHNEXT,JMP @A+DPTR ;转向形成的散转地址入口TAB,AJMP PROG0 ;直接转移地址表AJMP PROG1……AJMP PROGn例 4-9 在内部 RAM 20H和 21H单元中有两个无符号的数,由 22H中的值决定对该数完成加,减,乘或除运算 ( 20H单元的数为被减数或被除数 ),运算规则及结果保存处见表 4-1。表 4-1 例 4-9说明( 22H) 操作 结果保存处0 加 30H(低字节),31H(高字节 )1 减 40H2 乘 50H(低字节),51H(高字节 )3 除 60H(余数),61H(商 )ORG 1000HMOV A,22HMOV B,21HRL AMOV DPTR,#TABJMP @A+DPTRNOPTAB,AJMP ADDM ;散转表AJMP SUBMAJMP MULMAJMP DIVMADDM,MOV A,20H ;加法运算ADD A,BMOV 30H,AMOV A,#0ADDC A,#0MOV 31H,ASJMP FINISHSUBM,MOV A,20H ;减法运算SUBB A,BMOV 40H,ASJMP FINISHMULM,MOV A,20H ;乘法运算MUL ABMOV 51H,BMOV 50H,ASJMP FINISHDIVM,MOV A,20H ;除法运算DIV ABMOV 61H,AMOV 60H,BFINISH,END4.2.4 子程序设计子程序与一般程序的主要区别是在子程序的末尾有一条子程序返回指令 ( RET),其功能是执行完子程序后通过将堆栈内的断点地址弹出到PC而返回到主程序中 。在编写子程序时应注意以下几点:( 1) 要给每个子程序赋一个名字 。实际上是一个入口地址的代号 。( 2) 在子程序的末尾必须有子程序返回指令 RET。(3)要能正确地传递参数 。首先要有入口条件,说明进入子程序时它所要处理的数据如何得到,另外,要有出口条件,即处理的结果是如何存放的 。( 4) 注意保护现场和恢复现场。注意保存主程序和子程序共同涉及的,但值不同的累加器、寄存器和单元的内容。保护现场,PUSH恢复现场,POP( 5) 注意子程序的通用性。主程序调用子程序的指令:,LCALL”,,ACALL”。子程序返回指令,RET。子程序可以嵌套,嵌套次数从理论上说是无限的,但实际上由于受堆栈深度的影响,嵌套次数是有限的。例 4-10 在图 3-11 的 P1口与 LED的连接示意图中,若使得LED0~LED7依次点亮,其延时时间分别从 1s至 8s,LED7点亮之后又从 LED0开始循环。编写汇编语言源程序实现该功能 。C ORG 1000HMOV A,#1 ;主程序MOV R4,#0NEXT,INC R4C MOV P1,AC ACALL DELAYRL ASJMP NEXTDELAY,MOV R7,#10 ; 1s延时子程序DELAY3,MOV R6,#200DELAY2,MOV R5,#125DELAY1,DJNZ R5,DELAY1 ; 125× 4= 500μs= 0.5msDJNZ R6,DELAY2 ; 0.5 ms× 200= 0.1sDJNZ R7,DELAY3 ; 0.1s× 200= 1sDJNZ R4,DELAYRETEND例 4-11 两个无符号数据块的首地址分别为 30H和 40H,每个数据块的第一个字节都存放着数据块的长度(小于 15),求各数据块中最大值的乘积,并将结果存入 50H(乘积低字节)和 51H(乘积高字节)。解:可将求最大值的过程编写成一个子程序,子程序的入口参数是数据块的首地址,存放在 R1中,返回参数即为最大值,存放在 A中,参考程序如下,ORG 1000H ;主程序MOV R1,#30H ;置入口条件参数ACALL FMAX ;调用求最大值子程序MOV B,A ;第一个最大值存放于 BMOV R1,#40H ;置入口条件参数ACALL FMAX ;调用求最大值子程序MUL AB ;求乘积MOV 50H,A ;存乘积低字节MOV 51H,B ;存乘积低高字节SJMP $ORG 1200H ;子程序FMAX,MOV A,@R1 ;取数据块长度MOV R2,A ; R2中存放数据块的长度INC R1 ;改变地址指针MOV A,@R1 ;将第一个数放入 ADEC R2 ;数据个数减 1LOOP1,INC R1 ;修改地址指针CLR CSUBB A,@R1 ;相减比较大小JNC LOOP2 ; A中的数为大,跳向MOV A,@R1 ;否则,更换大数到 ASJMP LOOP3LOOP2,ADD A,@R1 ;恢复原最大值 LOOP3:LOOP3:DJNZ R2,LOOP1 ;若未比较完,则循环RETEND例,将 R0和 R1所指的内部 RAM中两个多字节无符号数相加,结果存入 R0所指的内部 RAM中 。NADD:CLR CNADD1:MOV A,@R0ADDC A,@R1MOV @R0,AINC R0INC R1DJNZ R7,NADD1JNC NADD2MOV @R0,#01HINC R0NADD2:DEC R0RET4.3 常用程序设计举例4.3.1 代码转换类程序计算机内部的运算一般都是用二进制,而在计算机与外设的数据传送中常采用 BCD码,ASCII码和其它代码,因此,就存在代码转换的问题 。 在程序设计中常采用 算法处理和查表方式 来实现代码转换 。1,十六进制数与 ASCII码之间的转换例 4-12 将从 30H单元开始的连续 8个单元中存放的十六进制数转换成其所对应的ASCII码,并分别存放在从 40H开始的 16个单元中。解,ORG 2000HMOV R0,#30H ;设定地址指针MOV R1,#40HMOV R7,#8 ;循环次数NEXT,MOV A,@R0 ;高字节转换SWAP AANL A,#0FHACALL HEXASMOV @R1,AINC R1MOV A,@R0 ;低字节转换ANL A,#0FHACALL HEXASMOV @R1,AINC R1 ;修改地址指针INC R0DJNZ R7,NEXTNOPSJMP $HEXAS,CLR C ;十六进制转换成 ASCII码子程序SUBB A,#10JC LOOPADD A,#7LOOP,ADD A,#10 ;补偿减掉的 10ADD A,#30HRETEND例 把外部 RAM 30H~3FH单元中的 ASCII码依次转换为十六进制数,并存入内部 RAM 60H~67H单元之中 。假设,被转换的 ASCII为 十六进制数 ( 0~F)的 ASCII,则,因为,0~9-- ASCII 30~39HA~F-- ASCII 41~46H若 ( 30H) = 41H-- A= 1041H- 30H= 11H= 17因为一个字节可装两个转换后得到的十六进制数,即两次转换才能拼装为一个字节。为了避免在程序中重复出现转换程序段,因此通常采用子程序结构,把转换操作编写为子程序。ORG 5000HMAIN,MOV R0,# 30H ;设置 ASCII码地址指针MOV R1,# 60H ;设置十六进制数地址指针MOV R7,# 08H ;字节个数AB,ACALL TRAN ;调用转换子程序SWAP A ; A高低字节交换MOVX @R1,AINC R0ACALL TRAN ; 调用转换子程序XCHD A,@R1 ;十六进制数拼装INC R0INC R1DJNZ R7,AB子程序 ( TRAN),TRAN,CLR CMOVX A,@R0 ;取 ASCII码SUBB A,#30HCJNE A,#0AH,BBAJMP BCBB,JC DONEBC,SUBB A,#07H ;大于等于 0AH,再减 07HDONE,RETEND例 4-13 将两字节十六进制整数转换成三字节的 BCD码 。 若待转换的双字节十六进制整数在 R6,R7中 ( R6中为高位 ),转换后的三字节 BCD码整数存于 R3,R4和 R5中 ( R3中为高位 ) 。解:二进制数 b7b6b5b4b3b2b1b0B所对应的十进制数 X可按照下式计算因此,只要按照十进制运算法则,将 bi( i=7,6,…,1,0)按权相加,就可以得到相应的十进制数 X。参考程序如下:ORG 2000HHEBCD,MOV A,#0 ; BCD码初始化MOV R3,AMOV R4,AMOV R5,AMOV R2,#16 ;循环次数NEXT,CLR CMOV A,R7 ; R7右移一位并送回RLC AMOV R7,AMOV A,R6 ; R6右移一位并送回RLC AMOV R6,AMOV A,R5 ;( R5) × 2并调整为 BCD码ADDC A,R5DA AMOV R5,AMOV A,R4 ;( R4) × 2并调整为 BCD码ADDC A,R4DA AMOV R4,AMOV A,R3ADDC A,R3MOV R3,A ;若万位数不超过 6,则不用调整DJNZ R2,NEXT ;处理完 16位了吗?NOPEND4.3.2 查表程序常用于非线性修正,非线性函数转换以及代码转换等 。专用的查表指令:MOVC A,@A+DPTR ;远程查表,64KB通过 以下三步操作实现查表 。·将所查表格的 首地址送入 DPTR;·将要查找的 数据序号,即数据在表中的位置送入 累加器 A中 ;·执行查表指令 MOVC A,@A+DPTR 进行读数并存结果存于累加器 A。MOVC A,@A+PC ;近程查表,0~+256B其实现查表也可通过以下三步操作来完成。· 将要查找的 数据序号,即数据在表中的位置 送入累加器 A中;· 把从 查表指令到表的首地址间的偏移量与 A值相加 ;· 执行查表指令 MOVC A,@A+PC 进行读数,查表结果送累加器 A。例 4-14 用查表指令编程实现将从 30H单元开始的连续 8个单元中存放的十六进制数转换成其所对应的 ASCII码,并分别存放在从 40H开始的 16个单元中 。ORG 2000HASCTAB,DB 30H,31H,32H,33H,34H,35H,36H,37H; ASCII码表DB 38H,39H,41H,42H,43H,44H,45H,46HMOV R0,#30H ;设定地址指针MOV R1,#40HMOV R7,#8 ;循环次数MOV DPTR,#ASCTABNEXT,MOV A,@R0 ;高字节转换SWAP AANL A,#0FHMOVC A,@A+DPTR ; 查表MOV @R1,AINC R1MOV A,@R0 ; 低字节转换ANL A,#0FHMOVC A,@A+DPTR ; 查表MOV @R1,AINC R1 ;修改地址指针INC R0DJNZ R7,NEXTNOPEND例 4-15 在一个巡回检测系统中,需对 8路输入进行控制,每路都有一最大允许值,为双字节数,且不全相同。控制时,需将输入值与最大值比较,若超过则进行报警。编写一子程序使其能查找每路的最大允许值。解:该查表运算中自变量 X是单字节,而因变量 Y是两字节的数。假设被检测路数存放在 R7中(入口参数),0~7路的最大允许值依次存放在 ROM中,查询得到的最大值存放在 30H(低字节)和 31H(出口参数)中,则参考程序如下:ORG 1000HMOV DPTR,#TABLEMOV A,R7RL A ;乘 2进行地址修正MOV R7,AMOVC A,@A+DPTR ;查表取高字节MOV 31H,AINC DPTRMOV A,R7MOVC A,@A+DPTR ;查表取低字节MOV 30H,ATABLE,DW H,H ; 最大允许值表DW H,HRET例 若累加器 A中存放的是一位 BCD码 。 通过查表将其转换成为相应的七段显示码,并存入寄存器 B中 。七段数码显示管连接方式:共阳极和共阴极两种 。共阳极是低电平为有效输入,共阴极为高电平为有效输入 。假设数码显示管为共阴极 。0~9的七段码为 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH。由于代码没有规律,一般采用查表完成 。h g f e d c b a0 0 1 1 1 1 1 1acedbgfh3FH若以 DPTR为基址,程序段如下:ORG 2000HMOV A,#05HMOV DPTR,#TABMOVC A,@A+DPTRMOV B,ASJMP $TAB,DB 3FH,06H,5BH,4FH,66H,DB 6DH,7DH,07H,7FH,6FH… …若以 PC为基地址,则程序段如下:… …MOV A,#05HADD A,#01HMOVC A,@A+PCNOPTAB,DB 3FH,06H,5BH,4FH,66H,DB 6DH,7DH,07H,7FH,6FH… …例 4-16 若内部 RAM 30H中存放的是一位 BCD码,通过查表将其转换成为相应的七段显示码,并存入寄存器 31H中。解,0~9的共阴极字形代码为 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH。ORG 1000HMOV A,30HADD A,#04H ;地址修正MOVC A,@A+PCMOV 31H,A ; 2字节指令SJMP $ ; 2字节指令TAB,DB 3FH,06H,5BH,4FH,66HDB 6DH,7DH,07H,7FH,6FHEND4.2.6 逻辑操作程序例 4-17 写出图 4-7所示电路的逻辑表达式,并编程实现其功能解:该电路图的最简逻辑表达式为,ORG 1000HX BIT P1.0 ;输入逻辑变量Y BIT P1.1Z BIT P1.2F BIT P1.3 ;输出逻辑变量EXOR,MOV C,XANL C,/YMOV F,C ;保存结果于 F位MOV C,YANL C,/XORL C,FANL C,ZMOV F,C ; F←()MOV C,XANL C,Y ; XYORL C,FMOV F,CEND图 4-7 例 4-17的逻辑电路图=1 & ≥11XYZ FXYZ)YX(F YXYXYX例 4-18 在图 3-7中,假设 K1,K2和 K3分别表示 X,Y和 Z三人对某一提案的表决,当 K闭合时,表示其同意该方案;当 K断开时,表示不同意该方案。当多数人同意时,输出 F为 1。假设 P1.7连接一共阴极 LED,将结果用 LED显示出来。编程实现此功能。解:根据数字电路中组合逻辑电路的设计知识,得出该逻辑电路的最简逻辑函数式是 F=XY+XZ+YZ,据此设计的参考程序如下:ORG 1000HX BIT P1.0Y BIT P1.1Z BIT P1.2MOV C,X ;实现 XYANL C,YMOV 20H,CMOV C,X ;实现 XZANL C,ZMOV 21H,CMOV C,Y ;实现 YZANL C,ZORL C,21HORL C,20HMOV P1.7,CNOPEND例 设 P1.0~P1.3为准备就绪信号输入端,当该 4位输入全为 1时说明各项工作已准备好,单片机可顺序执行主程序,否则循环等待 。ORG 2000HLOOP:MOV A,P1ANL A,#0FHCJNE A,#0FH,LOOPMAIN:例 用软件实现逻辑函数 。其中 X,Y,Z,W,F均为位变量,分别对应 P1.0,P1.1、P1.2,P1.3和 P1.7。 由开关为 P1.0,P1.1,P1.2,P1.3输入值,而由 P1.7输出该逻辑函数值 。X Y ZX Y Z WZYXFORG 5000HX BIT P1.0Y BIT P1.1Z BIT P1.2W BIT P1.3F BIT P1.7TEMP BIT 20H.0MOV C,XANL C,YANL C,Z ; C←XYZMOV TEMP,C ;暂存 XYZANL C,WORL C,TEMP ; C←XYZW + XYZMOV TEMP,CMOV C,XANL C,/YANL C,W ; C←ORL C,/TEMP ; C←MOV F,C ;输出最后结果END第 4 章 汇编语言程序设计思考题与习题4-1 把外部 RAM 5000H的内容拆开,高位送 5001H,低位送 5002H。4-2 把外部 RAM 3000H开始的 100字节的内容传送到从外部 RAM 3500H开始的连续单元中。4-3 设有 100个有符号数,连续存放在外部 RAM以2000H为首地址的存储区中,编程统计其中正数、负数和零的个数,并分别存放在 R5,R6和 R7。4-4 外部 RAM 1000H开始连续存放 20个双字节无符号数,低字节在前,高字节在后,编写求和程序,将结果存入内部 RAM 30H,31H,32H单元中。4-5 编程计算片内 RAM40H~47H单元中无符号数的算术平均值(假设和仍为 8位数),结果存放在 50H(商)和 51H(余数)中。4-6 从内部 RAM 30H开始存有一无符号数据块,其长度在 2FH单元中。求出数据块中最小值和最大值并分别存入 R6和 R7中。4-7 将上题中“无符号数”改为“有符号数”,求出其中的最小值和最大值(参考例 4-8)。4-8 从外部 RAM首地址为 1000H、长度为 50H的数据块中找出第一个 ASCII码‘ #’,并将其地址送到 1050H和 1051H单元中,如果没有‘ #’,则使 1050H和 1051H单元的内容为 0。4-9 把外部 RAM 30H~3FH单元中的 ASCII码依次转换为十六进制数,并存入内部 RAM 60H~67H单元之中。4-10 假设晶振频率 fosc =6MHz,根据图 3-11的线路设计灯亮程序。要求将 8只发光二极管间隔地分两组,每组 4只,两组交叉轮流发光,反复循环不止,每组灯亮持续时间为 1s。4-11 用软件实现逻辑函数 。其中 X,Y,Z,W,F均为位变量,分别对应 P1.0,P1.1,P1.2,P1.3和 P1.7。由 P1.0、P1.1,P1.2,P1.3输入值,而由 P1.7输出该逻辑函数值。4-1 把外部 RAM 5000H的内容拆开,高位送 5001H,低位送 5002H。MOV DPTR,#5000HMOVX A,@DPTRMOV R1,ASWAP AANL A,#0FHINC DPTRMOVX @DPTR,AMOV A,R1ANL A,#0FHINC DPTRMOVX @DPTR,A4-2 把外部 RAM 3000H开始的 100字节的内容传送到从外部RAM 3500H开始的连续单元中。MOV DPTR,#3000HMOV R7,#100LOOP:MOVX A,@DPTRMOV R1,AMOV A,DPHADD A,#5MOV DPH,AMOV A,R1MOVX @DPTR,AMOV A,DPHCLR CSUBB A,#05MOV DPH,ADJNZ R7,LOOP4-3 设有 100个有符号数,连续存放在外部 RAM以 2000H为首地址的存储区中,编程统计其中正数、负数和零的个数,并分别存放在 R5、R6和 R7。MOV DPTR,#2000HMOV R0,#100MOV R5,#0 ;正数个数MOV R6,#0 ;负数个数MOV R7,#0 ;0个数LOOP:MOVX A,@DPTRJZ ZEROJB ACC.7,NEGINC R5SJMP LOOP1NEG:INC R6SJMP LOOP1ZERO:INCR7LOOP1:DJNZ R0,LOOP4-4 外部 RAM 1000H开始连续存放 20个双字节无符号数,低字节在前,高字节在后,编写求和程序,将结果存入内部 RAM 30H,31H,32H单元中。MOV DPTR,#2000HMOV R7,#20MOV 30H,#0MOV 31H,#0MOV 32H,#0LOOP:MOVX A,@DPTRADD A,30HMOV 30H,AINC DPTRMOVX A,@DPTRADD A,31HMOV 31H,AJNC LOOP1INC 31HLOOP1:INC DPTRDJNZ R7,LOOP4-5 编程计算片内 RAM40H~47H单元中无符号数的算术平均值(假设和仍为 8位数),结果存放在 50H(商)和 51H(余数)中。MOV R0,#40HMOV R7,#8CLR CLOOP:ADD A,#@R0INC R0DJNZ R7,LOOPMOV B,#8DIV ABMOV 50H,AMOV 51H,B第 4 章 汇编语言程序设计4-6 从内部 RAM 30H开始存有一无符号数据块,其长度在 2FH单元中。求出数据块中最小值和最大值并分别存入 R6和 R7中 。MOV R0,#30HMOV A,@R0MOV R6,AMOV R7,ADEC 2FHLOOP:INC R0CLR CMOV A,R6SUBB A,@R0JNC MINCLR CMOV A,R7SUBB A,@R0JNC LOOP1MAX,MOV A,@R0MOV R7,ASJMP LOOP1MIN:MOV A,@R0MOV R6,ALOOP1:DJNZ 2FH,LOOP第 4 章 汇编语言程序设计4-8 从外部 RAM首地址为 1000H、长度为 50H的数据块中找出第一个 ASCII码‘ #’,并将其地址送到 1050H和 1051H单元中,如果没有‘ #’,则使 1050H和 1051H单元的内容为 0。C MOV DPTR,#1000HC MOV R7,#50HLOOP:MOVX A,@DPTRC CJNE A,#23H,LOOP1C SJMP DONE1LOOP1:INC DPTRC DJNZ R7,LOOPC CLR AC MOVX @DPTR,AC INC DPTRC MOVX @DPTR,AC SJMP DONEDONE1:MOV R1,DPLC MOV R2,DPHC MOV DPTR,#1050HC MOV A,R1C MOVX @DPTR,AC INC DPTRC MOV A,R2C MOVX @DPTR,ADONE:END第 4 章 汇编语言程序设计4-9 把外部 RAM 30H~3FH单元中的 ASCII码依次转换为十六进制数,并存入内部 RAM 60H~67H单元之中。ORG 5000HMAIN,MOV R0,# 30H ;设置 ASCII码地址指针MOV R1,# 60H ;设置十六进制数地址指针MOV R7,# 08H ;字节个数AB,ACALL TRAN ;调用转换子程序SWAP A ; A高低字节交换MOVX @R1,AINC R0ACALL TRAN ; 调用转换子程序XCHD A,@R1 ;十六进制数拼装INC R0INC R1DJNZ R7,AB第 4 章 汇编语言程序设计子程序 ( TRAN),TRAN,CLR CMOVX A,@R0 ;取 ASCII码SUBB A,#30HCJNE A,#0AH,BBAJMP BCBB,JC DONEBC,SUBB A,#07H ;大于等于 0AH,再减 07HDONE,RETEND第 4 章 汇编语言程序设计4-10 假设晶振频率 fosc =6MHz,根据图 3-11的线路设计灯亮程序。要求将 8只发光二极管间隔地分两组,每组 4只,两组交叉轮流发光,反复循环不止,每组灯亮持续时间为 1s。C ORG 1000HNEXT,MOV P1,#55HC ACALL DELAYC MOV P1,#0CCHC ACALL DELAYC SJMP NEXTDELAY,MOV R7,#10 ; 1s延时子程序DELAY3,MOV R6,#200DELAY2,MOV R5,#125DELAY1,DJNZ R5,DELAY1 ; 125× 4= 500μs= 0.5msDJNZ R6,DELAY2 ; 0.5 ms× 200= 0.1sDJNZ R7,DELAY3 ; 0.1s× 200= 1sRETEND第 4 章 汇编语言程序设计4-11 用软件实现逻辑函数 。其中 X,Y,Z,W,F均为位变量,分别对应 P1.0,P1.1,P1.2,P1.3和 P1.7。由 P1.0,P1.1,P1.2,P1.3输入值,而由 P1.7输出该逻辑函数值。4.2.8 实用程序设计举例( 1)排序类程序数据排序的算法有很多,常用的有冒泡排序法、插入排序法、选择排序法、二路归并排序法等。例 4.15:设在内部 RAM 30H单元连续存放了 8个单字节数据,编程实现按升序排列。ORG 2000HSTAR:MOV R0,#30HMOV R7,#07HCLR 00HLOOP:MOV A,@R0MOV 2BH,AINC R0MOV 2AH,@R0CLR CSUBB A,@R0JC NEXTMOV @R0,2BHDEC R0MOV @R0,2AHINC R0SETB 00HNEXT:DJNZ R7,LOOPJB 00H,STARSJMP $END习题 4-7:设内部 RAM的 30H和 31H单元中有两个带符号数,编写程序求出大数并存入内部 RAM的 32H单元 。ORG 4200HMOV A,30HXRL A,31HJB ACC.7,L1MOV A,30HCLR CSUBB A,31HJNC L2AJMP L3L1,MOV A,30HJNB ACC.7,L2L3,MOV 32H,31HAJMP L4L2,MOV 32H,30HSJMP $END习题 4-8:设 X为存放在内部 RAM 30H单元的无符号数,函数 Y存放在内部 RAM40H单元,编写满足下列关系的程序,ORG 4200HMOV A,30HCJNE A,#50H,LOOPAJMP AALOOP,JNC AACJNE A,#20H,LOOP2AJMP BBLOOP2,JC CCBB,MOV A,30HRL ARL AADD A,30HMOV 30H,AAJMP AACC,RL AMOV 30H,AAA,MOV 40H,30HEND习题 4-9:编写程序,求出内部 RAM 50H单元的数据含,1”的个数,并将结果存入 51H单元,MOV A,50HMOV 51H,#0MOV R1,#8LOOP:RLC AJNC LOOP1INC 51HLOOP1:DJNZ R1,LOOP习题 4-10,编写程序,将内部 RAM 30H~3FH单元的内容清零,ORG 4200HMOV R0,#30HMOV R7,#10HLOOP,MOV @R0,#0INC R0DJNZ R7,LOOPEND第 4 章 汇编语言程序设计习题 4-11:从内部 RAM 30H开始存有一无符号数据块,其长度在 2FH单元,求出数据块中最小值并存入 30H单元,ORG 4200HMOV R0,#30H ;数据区首地址MOV A,@R0 ;读第一个数DEC 2FHLOOP,INC R0MOV 20H,@R0 ;读下一个数CJNE A,20H,CHECK ;数值比较CHECK,JC LOOP1 ; A值大转MOV A,@R0 ;大数送 ALOOP1,DJNZ 2FH,LOOP ;未完,继续MOV 30H,A ;极值送 28H单元END习题 4-12,从外部 RAM 2000H单元起存放了 100个无符号数 。 统计其奇数和偶数的个数,并存放在内部 RAM 30H和 31H单元中 。ORG 4200HMOV DPTR,#2000HMOV R7,#100HMOV 30H,#0 ;QIMOV 31H,#0 ;OULOOP,MOVX A,@DPTRJB ACC.0,QIINC 31HAJMP AAQI,INC 30HAA,INC DPTRDJNZ R7,LOOPEND习题 4-13,将连续存放在外部 RAM 1000H开始的 100个单字节数据,传送到外部 RAM 2000H开始的连续地址单元中 。ORG 4200HMOV R7,#100MOV DPTR,#1000HLOOP,MOVX A,@DPTRMOV R0,AMOV A,DPHADD A,#10HMOV DPH,AMOV A,R0MOVX @DPTR,AMOV A,DPHCLR CSUBB A,#10HMOV DPH,AINC DPLDJNZ R7,LOOPEND习题 4-14,ORG 4200HMOV R7,#20MOV DPTR,#1000HMOV 30H,#0MOV 31H,#0MOV 32H,#0LOOP,MOVX A,@DPTRADD A,30HMOV 30H,AINC DPTRMOVX A,@DPTRADDC A,31HMOV 31H,AJNC LOOP1INC 32HLOOP1:INC DPTRDJNZ R7,LOOPEND习题 4-17:编写程序,实现 ∑2× i( i=1~10) 。 并将结果存放在内部 RAM 50H单元中 。ORG 4200HMOV R0,#10MOV 50H,#0LOOP,MOV A,R0RLAADD A,50HMOV 50H,ADJNZ R0,LOOPEND
课件名称:课件分类:计算机课件类型:教学课件文件大小:12.36MB下载次数:36评论次数:9用户评分:5.7
11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29.

我要回帖

更多关于 通晓四种语言 的文章

 

随机推荐