470 likes | 559 Vues
知识点. 1. 汇编语言格式 2. 汇编语言的伪指令 3. 顺序结构程序 4. 分支结构程序 5. 循环结构程序 6. 子程序. 汇编. 低级语言. 机器语言. 反汇编. 编译. 高级语言. 机器语言. 反编译. 源程序 目标程序. 机器语言 : 机器语言是用二进制代码表示的计算机能直接识别和执行的一种机器指令的集合。 汇编语言 : 汇编语言 (Assembly Language) 是一种低级的面向机器的程序设计语言。 汇编语言源程序 : 用汇编语言编写的程序 .
E N D
知识点 1.汇编语言格式 2.汇编语言的伪指令 3.顺序结构程序 4.分支结构程序 5.循环结构程序 6.子程序
汇编 低级语言 机器语言 反汇编 编译 高级语言 机器语言 反编译 源程序 目标程序
机器语言:机器语言是用二进制代码表示的计算机能直接识别和执行的一种机器指令的集合。机器语言:机器语言是用二进制代码表示的计算机能直接识别和执行的一种机器指令的集合。 汇编语言:汇编语言(Assembly Language)是一种低级的面向机器的程序设计语言。 汇编语言源程序:用汇编语言编写的程序. 编译程序:编译程序也叫编译系统,是把用高级语言(如:C语言)编写的面向过程的源程序翻译成目标程序的语言处理程序。
汇编语言程序设计实例引入 实例 假设一个班有50个人, 共有3门选修课: 计算机算法 CAD设计 单片机 请找出: 同时选了三门课的同学;
找出第一个学生 N 他选算法吗? Y N 他选CAD吗? Y N 他选单片机吗? Y 记录要找的人 N 还有学生吗? Y 结束 下一个学生 重复49次
为什么要用流程图? • 符合人进行逻辑思考的习惯 • 计算机从根本上来说,没有任何逻辑性,所以,你必须告诉它,先做什么,后做什么,遇到什么情况又该做什么,等等 • 流程图设计本身是一个逐步求精的过程,最终将任务划分为若干能由机器指令实现的小模块
程序设计的基本步骤 • 题意分析 • 画出流程图 • 分配内存及端口 • 编制源程序 • 仿真、调试程序 • 固化程序 • 下面开始学习汇编语言的相关知识
汇编语言的格式 伪指令(Pseudo—Instruction) 在汇编语言源程序中用MCS-51指令助记符编写的程序,一般都可以一一对应地产生机器码,这种指令是真正意义上的指令。 如:MOV A,#68H的机器码为74H、68H LJMP 2000H的机器码为02H、20H、00H 这些指令在第三章中已经详细介绍。
但还有一些指令不产生机器码,即没有对应的机器码,也就是说它不是CPU能执行的指令,只是提供汇编控制信息,以便在汇编时执行一些特殊的操作,这种指令称为伪指令。 如:1000H: DB 20H 没有对应的机器码,但这条伪指令所要完成的功能是将地址为1000H的存储单元的内容定义成20H。
常用伪指令 定位伪指令ORG 定义字节数据伪指令DB 定义字数据伪指令DW 定义空间伪指令DS 符号定义伪指令EQU或= 数据赋值伪指令DATA 位地址定义指令BIT 汇编结束伪指令END
伪指令的格式 : [标号:] 操作码 <项或项表>[;注释] 其中: 方括号为可选项 ,标号可要可不要;注释是编程者附加的说明,也是可要可不要。 尖括号为必选项,可以是单项,也可以是多项 操作码为必选项,该项为ORG、DB、DW、DS、EQU、DATA、BIT、END等8项中的任意一项。 下面分别介绍这些伪指令的功能:
1.设置起始地址ORG(Origin) • ORG <nn> • 其中,ORG是该伪指令的操作码助记符,操作数nn是16位二进制数(或者是4位十六进制数),前者表明为后续源程序经汇编后的目标程序安排存放位置,后者则给出了存放的起始地址值。 • ORG伪指令总是出现在每段源程序或数据块的开始,它可以让我们把主程序、子程序或数据块存放在存储器的任何位置。若在源程序开始不放ORG指令,则汇编将从0000H单元开始编排目标程序。
例如: ORG 2000H MOV SP, #60H( 栈指针寄存器SP的地址=81H) MOV R0, #2FH MOV R2, # 0FFH ORG伪指令说明其后面程序的目标代码在程序存储器中存放的起始地址是2000H, 即 存储器地址 目标程序 2000H 75 81 60 2003H 78 2F 2005H 7A FF 程序存储器 2000H 2006H
2.定义字节DB(Define Byte) • [标号] DB <项或项表> • 其中,项或项表是指一个字节的数、字符串 • 或以引号括起来的ASCII码字符串(一个字符用 • ASCII码表示,就相当于一个字节)。 • 该指令的功能是把项或项表的数值存入从标号开始的连续单元中。
程序存储器 1000H 1005H 例如:ORG 1000H SEG1: DB 53H,78H,"2" SEG2: DB 'DAY' END 则: (1000H)=53H (1001H)=78H (1002H)=32H (1003H)=44H (1004H)=41H (1005H)=59H 并且SEG1代表1000H、SEG2代表1003H 注意:作为操作数部分的项或项表,若为数值,其取值范围应为 00~FFH;若为字符串,其长度应限制在80个字符内。
程序存储器 2200H 2006H 3.定义字DW(define word) • [标号:] DW <项或项表> • DW的基本含义与DB相同,不同的是DW定义16位数据,常用来建立地址表。 • 【例4-3】 2200H:DW l234H,08H • 则: • (2200H)=12H • (2201H)=34H • (2202H)=00H • (2203H)=08H • 注意:08H表面看是字节,在DW后是0008H
程序存储器 3000H 这里数据是不定的 3007H 4.预留存储区(定义空间)DS(DehneStorage) • [标号:] DS <表达式> • 该指令的功能是由标号指定单元开始,定义一个存储区,以备源程序使用。存储区内预留的存储单元个数由表达式的值决定。 • 例如: ORG 3000H SEG:DS 06H DB 30H,40H 上例表示从3000H单元开始, 连续预留6个存储单元,然后从 3006H单元开始按DB命令给内 存单元赋值。 即:(3006H)=30H,(3007H)=40H。
5.为标号赋值EQU(Equate) • [标号] EQU <数或汇编符号> • 其功能是将操作数段中的地址或数据赋予标号字段的标号,故又称为等值指令。 注意:这里的标号后不能要“:” 例如:SG EQU R0 ;SG与R0等值 DE=40H ;DE与40H等值 MOV A,SG ;(R0) →(A) MOV R7,DE ;(40H) →(R7)
6.数据地址赋值DATA • [标号] DATA <数或表达式> • DATA命令的功能和EQU类似,但有以下差别: • (1)用DATA定义的标识符汇编时作为标号登记在符号表中,所以,可以先使用后定义,而EQU定义的标识符必须先定义后使用。 • (2)用EQU可以把一个汇编符号赋给字符名,而DATA只能把数据赋给字符名。 • (3)DATA可以把一个表达式赋给字符名,只要表达式是可求值的。
DATA常在程序中用来定义数据地址。 例如:MAIN DATA 2000H MAIN0 DATA MAIN+8 汇编后: MAIN的值为2000H MAIN0的值为2008H
7.位地址符号BIT • 字符名 BIT <位地址> • 其功能是把位地址赋予字符名。 • 例如: MN BIT Pl.7 • G5 BIT 02H • 汇编后,位地址P1.7、02H分别赋给变量MN和G5。 • 在进行位操作时MN和P1.7、G5和02H的意义完全相同。
8.源程序结束END • [标号:] END [表达式] • END命令通知汇编程序结束汇编。在END之后,所有的汇编语言指令均不予以处理。 • 每一个完整的汇编语言源程序的后面必须有END,否则,编译程序在对汇编语言源程序进行编译时,因找不到尾端而无法进行编译。
汇编语言的格式 汇编语言是面向机器的程序设计语言,对于不同CPU的微型机,其汇编语言一般是不同的,但是,它们之间所采用的语言规则有很多相似之处。在此,我们以MCS-51的汇编语言为例来说明汇编语言的规范。 汇编语言源程序是由汇编语句(指令语句)构成的。汇编语句由四个部分构成,每一部分称为一个字段,汇编程序能够识别它们。
MCS-51汇编语言的语句格式: [标号:]ㄩ[操作码] ,[操作数][;注释] ㄩ:空格 每个字段之间要用分隔符分开,而每个字段内部不能使用分隔符。 可以作为分隔符的符号有空格、冒号、逗号、分号等。
特别说明:在汇编程序中,除伪指令EQU、DATA、BIT前面的标号后面不用“:”以外,其它标号后面都用“:”特别说明:在汇编程序中,除伪指令EQU、DATA、BIT前面的标号后面不用“:”以外,其它标号后面都用“:” 例如: LOOP:MOV A, R0 ;(R0)→A 标号 操作码 目的操作数 源操作数 注释 下面分别解释这四个字段的含义: 1)标号:标号是用户设定的一个符号,表示存放指令的存储单元的地址。标号由以字母开始的1—8个字母或数字串组成,以冒号结尾。不能用指令助记符、伪指令或寄存器名来作标号。 标号是任选的,并不是每条指令或数据存储单元都要标号,只在需要时才设标号,如转移指令所要访问的存储单元前面一般要设置标号。 一旦使用了某标号定义一地址单元,在程序的其它地方就不能随意修改这个定义,也不能重复定义。
思考题 XX,XX,XX,XX,XX 00H,01H,04H,09H 1625H 30H,31H,34H,39H 标号 操作码 目的操作数 源操作数 1、读下面程序,指出执行各伪指令后相关单元对应内容是什么?未知内容用“XX”表示。 ORG 0F00H DS 05H DB 0,1,4,9 DW 1625H DB ‘0’,‘1’,‘4’,‘9’ END 2、指出下面一条指令的各部分的名称,并说明每部分的功能。 MAIN:ORL 56H,#56H
汇编语言程序设计 计算机完成某一具体的工作任务,必须按序执行一条条指令。这种按工作要求编排指令序列的过程称为程序设计(或编程)。 用汇编语言编写一个程序的过程大致可分为: ① 确定计算方法,定出运算步骤和顺序,把运算过程画成框图。 ② 确定数据,包括工作单元的数量,分配存放单元。 ③ 按所使用计算机的指令系统,把确定的运算顺序(框图)写成汇编语言程序。
顺序结构程序 顺序结构程序是一种最简单、最基本的程序,按照程序编写的顺序依次执行,编写这类程序主要应注意正确地选择指令,提高程序的执行效率和尽可能节省存储空间。
开始 (22H)A (32H)+AA 十进制调整 A(42H) (23H)A (33H)+AA 十进制调整 A(43H) 结束 例如:有两组BCD码(如:1183H和5678H),分别存放在23H、22H单元和33H、32H单元,求它们的和,并送入43H、42H单元中去。(高位在前,低位在后) 解:
开始 (22H)A (32H)+AA 十进制调整 A(42H) (23H)A (33H)+AA 十进制调整 A(43H) 结束 此条加法指令可否改用带进位的(ADD)? ORG 0000H MOV A,22H ADD A,32H DA A MOV 42H,A MOV A,23H ADDC A,33H DA A MOV 43H,A SJMP $ END 此条加法指令可否改用带进位的(ADDC)?
分支程序 分支结构程序可根据程序要求无条件或有条件地改变程序执行的顺序,选择程序流向。 编写这类结构的程序主要是为了正确使用转移指令,即无条件转移、条件转移和散转。
如果说顺序程序是1个入口1个出口 分支程序是1个入口2个出口,2个出口中究竟选择哪1个出口,根据条件决定,如满足条件A就选择A出口,不满足则选择B出口 入口 满足条件A? 出口A 常用指令有: JC REL JB REL JZ REL 等 出口B
分支程序的典型实例 正数标志位 负数标志位 想一想:程序怎么编写? 0000,0011 1000,0011 • 实例:已知VAR(30H单元)中有一变量X,要求编写一程序按下述要求给Y赋值,结果存入FUNC(31H)单元。 +1, X>0 Y = 0 , X = 0 –1 , X<0 • 题意:根据X的不同,程序编写时有三个出口,即有三个分支!!!!
分支程序实例---三分支程序 开始 程序框图: XA Y A=0? N Y A>0? N A= –1 A= 1 存结果 结束
分支程序实例---三分支程序 最高位为符号位。 源程序如下: ORG 2000H MOV A,30H JZ LP1 ;X = 0,转LP1处理 JNB ACC.7,LP2;X>0,转LP2处理 MOV A,#0FFH;X<0,则Y= –1 SJMP LP1 LP2:MOV A,#01;X >0,Y=1 LP1:MOV 31H,A;存结果 SJMP $;循环等待,$表示转至 本地址,此方法适用 于一字节的偏移量
散转程序 A中内容为8位无符号数0~255 16位地址数 + DPTR A PC • 散转程序是指通过修改某个参数后,程序可以有三个以上的流向,多用于键盘程序。 • 常用的指令是JMP @A+DPTR,该指令是把16位数据指针DPTR的内容与累加器A中的8位无符号数相加,形成地址,装入程序计数器PC,形成散转的目的地址。
例如:128种分支转移程序。根据入口条件转移到128个目的地址。例如:128种分支转移程序。根据入口条件转移到128个目的地址。 根据R7的内容,转向各自对应的操作程序(R7= 0,转入BRAN0;R7= 1,转入BRAN1…R7= n,转入BRANn) 程序清单如下: JMP-128: MOV A,R7 RL A ;R72A (修正变址值) MOV DPTR,#JPTAB ;跳转表首送数据指针 JMP @A+DPTR ;转向形成的散转地址人口 JPTAB : AJMP BRAN0 ;直接转移地址表 AJMP BRAN1 . AJMP BRANn 通过前面的学习,我们知道AJMP addr11是2字节指令,所以这里×2。 如果将AJMP addr11换成LJMP addr16,则这里×3。
循环结构程序 • 在程序设计中,常遇到反复执行某一段程序,此时可用循环程序结构,这有助于缩短程序,提高程序的质量。 循环结构的程序一般包括下面几个部分: • 1.置循环初值 置循环初值是设置用于循环过程工作单元的初始值。例如,设置循环次数计数器、地址指针初值、存放和数的单元初值等。 • 2.循环体 重复执行的程序段部分。 • 3.循环修改 在单片机中,一般用一个工作寄存器Rn作为计数器,给这个计数器赋初值作循环次数,每循环一次,对其进行修改。 • 4.循环控制 判断控制变量是否满足终值条件,不满足则转去重复执行循环工作部分,满足则顺序执行,退出循环。
开始 外循环次数 内循环次数 延时 N 循环次数到否? 循环次数到否? 2重循环初值 循环体 内循环 循环控制 Y N 循环N次到否? Y 结束 外循环
循环程序设计 延时程序清单: ORG 2000H 指令周期 MOV R0,#0AH 2个T机器 DEL2: MOV R1,#MT 2个T机器 DEL1: NOP 1个T机器 NOP 1个T机器 DJNZ R1,DEL1 2 个T机器 DJNZ R0,DEL2 2个T机器 RET 延时时间怎样计算? 指令周期、机器周期T机器与时钟周期T时钟的关系: T机器=12T时钟=121/fosc=1us (假设晶振频率fosc为12M) 延时时间的简化计算结果: (1+1+2) 1us 10 MT 若想延时10ms,只需修改计数初始值MT,即(1+1+2) 10250us=10ms
子程序设计 主要内容: 1. 主程序与子程序的关系 2. 子程序嵌套 3. 子程序的调用与返回 • 在实际问题中,常常会遇到在一个程序中多次用到相同的运算或操作,若每遇到这些运算或操作,都从头编起,将使程序繁琐、浪费内存。因此在实际中,经常把这种多次使用的程序段,按一定结构编好,存放在存储器中,当需要时,可以调用这些独立的程序段。通常将这种可以被调用的程序段称为子程序。
子程序SUB 主程序与子程序的关系 子程序入口地址 主程序MAIN 调用子程序 LCALL SUB RET 返回
取第一个数→A 调用查表子程序 结果存入R1 取下一个数→A 调用查表子程序 两数平方相加 存结果 例如:用程序实现c=a2+b2,设a、b、c分别存于内部RAM DA、DB、DC三个单元。 编程说明:这个问题可以用子程序来实现,即通过调用子程序查平方表,结果在主程序中相加得到。 程序框图如右图所示。
取第一个数→A 调用查表子程序 结果存入R1 取下一个数→A 调用查表子程序 两数平方相加 存结果 主程序如下: STAR: MOV A,DAH ACALL SQR ;调查表程序 MOV R1,A ;a2暂存R1中 MOV A,DBH ACALL SQR ;调查表程序 ADD A,R1 MOV DCH,A SJMP $ ;等待 子程序如下: SQR: INC A ;RET占用一个字节 MOVC A,@A+PC ;查平方表 RET TAB: DB 0,1,4,9,16 DB 25,36,49,64,81 END 该子程序入口条件(A)=待查表的数,出口条件(A)=平方值。
思考题 39 33 1、读程序,回答问题 ORG 1000H MOV A,#39H MOV B,A ANL A,#0FH ADD A,#30H MOV R0,A MOV A,B ANL A,#0F0H SWAP A ADD A,#30H MOV R1,A SJMP $ END R0=?、R1=?
思考题 MOV R0,#50 L2:MOV R1,#50 L1:MOV R3,56H DJNZ R1,L1 DJNZ R0,L2 SJMP $ MOV R0,#2 ACALL L1 MOV R1,A MOV R0,#4 ACALL L1 ADD A,R1 SJMP $ L1:MOV A, R0 MOV B,R0 MUL AB MOV B,R0 MUL AB RET 1、已知8051使用的晶振频率为12MHZ,设计一个软件延时程序,延时时间为10MS。 2、利用子程序知识,设计一程序求A=23+43。