第4章 程序设计_第1页
第4章 程序设计_第2页
第4章 程序设计_第3页
第4章 程序设计_第4页
第4章 程序设计_第5页
已阅读5页,还剩28页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、1汇编语言程序设计C和汇编的函数相互调用 2计算计算1 1100100的累加和的累加和汇编必须有一个主函数的标号汇编必须有一个主函数的标号“_main”_main”,而且必须声明此而且必须声明此“_main”_main”为全局型标号。为全局型标号。用户不用考虑程序代码的实际的物理地址,用户不用考虑程序代码的实际的物理地址,而是通过伪指令通知编译器把程序代码定位而是通过伪指令通知编译器把程序代码定位在什么类型的存储单元,具体地址由编译器在什么类型的存储单元,具体地址由编译器管理。管理。程序用伪指令程序用伪指令.RAM.RAM在数据存储区内声明了一在数据存储区内声明了一个变量个变量G_Sum,G_

2、Sum,变量名变量名G_SumG_Sum实际上代表了实际上代表了变量的地址变量的地址, ,对变量进行读写操作时,则需要对变量进行读写操作时,则需要用用G_SumG_Sum来表示变量中的实际内容。来表示变量中的实际内容。C C的编译器的编译器GCCGCC把把C C语言代码编译为汇编代语言代码编译为汇编代码,汇编编译器码,汇编编译器Xasm16Xasm16对汇编代码进行编对汇编代码进行编译成为目标文件。链接器将目标文件、库函译成为目标文件。链接器将目标文件、库函数模块、资源文件连接成整体,形成一个可数模块、资源文件连接成整体,形成一个可在芯片上运行的可执行文件。在芯片上运行的可执行文件。伪指令程序

3、指令立即数31.汇编语言语句格式汇编语言语句格式: 标号:标号: 指令指令 ;或;或/ 标号标号以冒号结束,作为指令所在地址的符号表示。标号按使以冒号结束,作为指令所在地址的符号表示。标号按使用范围分为全局标号和局部标号两种;用范围分为全局标号和局部标号两种; 指令指令分为硬指令和伪指令两种;分为硬指令和伪指令两种; 注释注释仅作为程序编写与阅读时的参考,汇编器不对其作任何仅作为程序编写与阅读时的参考,汇编器不对其作任何处理。注释行必须用分号处理。注释行必须用分号(;)或双斜线或双斜线(/)起始,可与指令在起始,可与指令在同一行,也可在指令的前一行或后一行同一行,也可在指令的前一行或后一行。

4、伪指令伪指令不必区分字母的大小写,但所有定义的标号包括宏名、不必区分字母的大小写,但所有定义的标号包括宏名、结构名、结构变量名、段名及程序名,其字母大小写一律区结构名、结构变量名、段名及程序名,其字母大小写一律区分开。分开。42.数制、数据类型与参数数制、数据类型与参数 nSP的汇编器将十进制作为默认数制。十六进制可用的汇编器将十进制作为默认数制。十六进制可用符号符号0 x或或$作为前缀,或用符号作为前缀,或用符号H作为后缀。作为后缀。数制后缀二进制B八进制O或Q十进制D或不写十六进制HASCII字符串用双引号或单引号括起52.数制、数据类型与参数数制、数据类型与参数 nSP汇编指令中所用的数

5、据类型汇编指令中所用的数据类型 汇编指令中的参数可以是常数,也可以是表达式。常数参汇编指令中的参数可以是常数,也可以是表达式。常数参数基本有数值型和字符串型两种。数基本有数值型和字符串型两种。63.全局标号与局部标号全局标号与局部标号 全局标号全局标号是指在源程序的是指在源程序的各个程序段中均能调用各个程序段中均能调用的标号,的标号,而局部标号则指而局部标号则指仅在各个所定义的程序段中调用仅在各个所定义的程序段中调用的标号的标号。 全局标号原则上可以由任意数量的字母和数字字符组成,全局标号原则上可以由任意数量的字母和数字字符组成,但只有但只有前前32位位是是有效有效的。它可以写在文件中的任何一

6、行上,的。它可以写在文件中的任何一行上,但但必须以字母字符或下划线(必须以字母字符或下划线(_)开头)开头,且,且标号名后须以冒标号名后须以冒号(:)来结束号(:)来结束。73.全局标号与局部标号全局标号与局部标号 局部标号只有在局部标号只有在局部区域内定义局部区域内定义才有效。正是这种约束才才有效。正是这种约束才使得局部标号的定义可以安全地重复使用在整个程序各处使得局部标号的定义可以安全地重复使用在整个程序各处而不致产生混乱错误。而不致产生混乱错误。 局部标号也像全局标号那样局部标号也像全局标号那样最多可有最多可有32个字母或数字字符个字母或数字字符,且且必须以字母字符或问号(?)开头必须以

7、字母字符或问号(?)开头。nSP的汇编器的汇编器通常规定用问号(?)作为局部标号的前缀或后缀。通常规定用问号(?)作为局部标号的前缀或后缀。 在不同的局部区域里所定义的局部标号都有不同的含义,在不同的局部区域里所定义的局部标号都有不同的含义,且标号且标号?a是不同于标号是不同于标号a?的。的。 切忌将诸如切忌将诸如“+、-、*、/”这类运算符用在局部标号中。这类运算符用在局部标号中。 8 程序的最基本结构形式有顺序、分支、循环、子程序四种程序的最基本结构形式有顺序、分支、循环、子程序四种结构。结构。 分支结构分为分支结构分为双分支结构双分支结构和和多分支结构多分支结构两种。在程序体中,两种。在

8、程序体中,根据不同的条件执行不同的动作,在某一确定的条件下,根据不同的条件执行不同的动作,在某一确定的条件下,只能执行多个分支中的一个分支。只能执行多个分支中的一个分支。 由于高级语言提供了由于高级语言提供了IF. ELSE语句,使得分支结构的层语句,使得分支结构的层次清晰,分支路径明确。然而次清晰,分支路径明确。然而在汇编语言在汇编语言中,只能依靠中,只能依靠跳跳转语句转语句实现这样的结构。实现这样的结构。9汇编语言实现分两分支路径的方式 汇编语言实现多重分支方式 10 循环程序可以有两种结构形式,一种是循环程序可以有两种结构形式,一种是WHILE_DO结构形结构形式;另一种是式;另一种是D

9、O_WHILE结构形式。结构形式。 循环程序一般由循环程序一般由3个主要部分组成:个主要部分组成:初始化部分初始化部分、循环体循环体。循环控制部分循环控制部分。WHILE_DO结构DO_WHILE结构11程序程序举例:数据搬运举例:数据搬运 把内存中地址为把内存中地址为0 x00000 x00000 x00060 x0006中的数据,移到地址为中的数据,移到地址为0 x00100 x00100 x00160 x0016中中.IRAM .IRAM Label: Label: .DW 0 x0001,0 x0002,0 x0003,0 x0004,0 x0005,0 x0006,0 x0007;

10、.DW 0 x0001,0 x0002,0 x0003,0 x0004,0 x0005,0 x0006,0 x0007; .VAR C_Move_To_Position=0 x0010; /.VAR C_Move_To_Position=0 x0010; /定义起始地址;定义起始地址; .CODE .CODE .PUBLIC _main; .PUBLIC _main; _main: _main: R1=7; / R1=7; /设置要移动的数据的个数设置要移动的数据的个数 R2=C_Move_To_Position; R2=C_Move_To_Position; BP=Label; BP=Lab

11、el; L_Loop: L_Loop: R3=BP; / R3=BP; /被移动的数据送入被移动的数据送入r3 r3 R2=R3; / R2=R3; / 被移动的数据送往目的地址被移动的数据送往目的地址 BP+=1; / BP+=1; /源地址加源地址加1 1 R2=R2+1; / R2=R2+1; /目的地址加目的地址加1 1 R1-=1; / R1-=1; /计数减计数减1 1 JNZ L_Loop; JNZ L_Loop; MainLoop: MainLoop: jmp MainLoop; jmp MainLoop; .END.END12 在某些问题的处理中,仅采在某些问题的处理中,仅采

12、用单循环往往不够,还必须用单循环往往不够,还必须采用多重循环才能解决。采用多重循环才能解决。 所谓所谓多重循环多重循环是指在循环程是指在循环程序中嵌套有其它循环程序。序中嵌套有其它循环程序。 多重循环程序设计的基本方多重循环程序设计的基本方法和单重循环程序设计是一法和单重循环程序设计是一致的,应分别考虑各重循环致的,应分别考虑各重循环的的控制条件控制条件及其程序实现,及其程序实现,相互之间不能混淆。相互之间不能混淆。多重循环结构 13 实际应用中,经常会遇到在同一程序中,须要多次进行一实际应用中,经常会遇到在同一程序中,须要多次进行一些相同的计算和操作,可以采用子程序的概念,将一些重些相同的计

13、算和操作,可以采用子程序的概念,将一些重复使用的程序标准化,使之成为一个独立的程序段,需要复使用的程序标准化,使之成为一个独立的程序段,需要时调用即可,我们就把这些程序段称作为子程序。时调用即可,我们就把这些程序段称作为子程序。 子程序的结构包括三个部分:子程序的结构包括三个部分:1.子程序的定义声明和开始子程序的定义声明和开始标号部分;标号部分;2.子程序的实体内容部分,表明程序将进行怎子程序的实体内容部分,表明程序将进行怎样的操作;样的操作;3.子程序的结束标号部分。子程序的结束标号部分。14 程序的调用包括主程序调用子程程序的调用包括主程序调用子程序,子程序调用子程序等。程序序,子程序调

14、用子程序等。程序调用是通过调用指令调用是通过调用指令CALL来实来实现的。现的。 程序执行的过程中,当遇到调用程序执行的过程中,当遇到调用子程序指令,子程序指令,CPU便会将便会将下一条下一条指令的地址压入堆栈指令的地址压入堆栈暂时保护起暂时保护起来,然后转到被调用的子程序入来,然后转到被调用的子程序入口 去口 去 执 行 子 程 序执 行 子 程 序 , 当 执 行 到, 当 执 行 到RETF时返回,时返回,CPU又将又将堆栈中堆栈中的返回地址弹出送到的返回地址弹出送到PC,继续执,继续执行原来的程序。行原来的程序。子程序调用过程 15 在程序调用的过程中,需要注意到的问题是在程序调用的过

15、程中,需要注意到的问题是断点的现场保断点的现场保护护。通常的做法是用。通常的做法是用堆栈堆栈对现场进行保护,在子程序开始对现场进行保护,在子程序开始就把子程序就把子程序要破坏掉的寄存器的内容压栈保护要破坏掉的寄存器的内容压栈保护,当子程序,当子程序结束的时候,再结束的时候,再弹栈恢复现场弹栈恢复现场。 程序调用的过程都伴随着程序调用的过程都伴随着参数的传递参数的传递,正确的参数传递要,正确的参数传递要满足满足入口入口和和出口出口条件。条件。16 入口条件入口条件指执行子程序时所必需的有关寄存器内容或源程指执行子程序时所必需的有关寄存器内容或源程序的存储器的存储地址等,主程序调用子程序时必须先满

16、序的存储器的存储地址等,主程序调用子程序时必须先满足入口条件,即足入口条件,即满足子程序对输入参数的约定。满足子程序对输入参数的约定。 出口条件出口条件就是指子程序执行完后将就是指子程序执行完后将运算结果所存放的寄存运算结果所存放的寄存器或存储器地址器或存储器地址等,也就是说,等,也就是说,必须确定主程序对输出参必须确定主程序对输出参数的约定。数的约定。 参数的传递有以下几种情况:参数的传递有以下几种情况: 1) 通过寄存器传递通过寄存器传递 2) 通过变量传递通过变量传递 3) 通过堆栈传递通过堆栈传递 17(1)通过寄存器传递参数通过寄存器传递参数 寄存器传递参数,是最常用的一种参数传递的

17、方式。我们寄存器传递参数,是最常用的一种参数传递的方式。我们常用到的传递参数的寄存器有常用到的传递参数的寄存器有4个个,分别为,分别为R1R4。 在程序调用的过程中,寄存器中的值也会被带到被调用的在程序调用的过程中,寄存器中的值也会被带到被调用的子程序中供子程序使用。子程序运算结束后返回主程序,子程序中供子程序使用。子程序运算结束后返回主程序,这些寄存器的新值也会被带到主程序中继续参加主程序的这些寄存器的新值也会被带到主程序中继续参加主程序的运算。运算。通过寄存器传递参数 18(2)通过变量传递参数通过变量传递参数 通过变量进行的参数传递,主要是通过通过变量进行的参数传递,主要是通过全局型变量

18、全局型变量实现的。实现的。 如果在某个汇编文件中定义了一个全局变量(如果在某个汇编文件中定义了一个全局变量(.PUBLIC),那),那么此汇编文件中的所有汇编代码都能够使用这个变量。同时该么此汇编文件中的所有汇编代码都能够使用这个变量。同时该变量也起到了参数传递的作用。变量也起到了参数传递的作用。 利用变量传递参数 19(3)通过堆栈传递参数通过堆栈传递参数 在在C函数与汇编函数的相互调用过程中,主要函数与汇编函数的相互调用过程中,主要通过堆栈来传递通过堆栈来传递参数参数,而在函数返回时,则,而在函数返回时,则采用寄存器来传递返回值采用寄存器来传递返回值。 在主程序把要传递的参数压入堆栈,然后

19、调用子程序。子程序在主程序把要传递的参数压入堆栈,然后调用子程序。子程序从堆栈中寻找需要的参数进行处理。当子程序返回后,主程序从堆栈中寻找需要的参数进行处理。当子程序返回后,主程序需要进行弹栈处理,以恢复参数压入堆栈前的堆栈状态。需要进行弹栈处理,以恢复参数压入堆栈前的堆栈状态。 IDE开发环境中的开发环境中的C语言与汇编语言的相互调用就是采用堆栈传语言与汇编语言的相互调用就是采用堆栈传递参数及寄存器返回参数的方式。递参数及寄存器返回参数的方式。堆栈传递参数 201.子程序的嵌套子程序的嵌套 子程序嵌套就是指子程序调用子程序。其中嵌套的层数称为嵌套深度。子程序嵌套就是指子程序调用子程序。其中嵌

20、套的层数称为嵌套深度。211.子程序的嵌套子程序的嵌套 子程序嵌套要子程序嵌套要注意注意以下几个方面:以下几个方面: (1)寄存器的保护和恢复,以避免各层子程序之间发生因)寄存器的保护和恢复,以避免各层子程序之间发生因寄存器冲突而出错的情况。寄存器冲突而出错的情况。 (2)程序中如果使用了堆栈来传递参数,应对堆栈小心操)程序中如果使用了堆栈来传递参数,应对堆栈小心操作,避免堆栈使用不当造成子程序不能正确返回的出错情作,避免堆栈使用不当造成子程序不能正确返回的出错情况。况。(3)子程序的嵌套层数不是无限的。堆栈是在数据存储区)子程序的嵌套层数不是无限的。堆栈是在数据存储区内开辟的空间,内开辟的空

21、间,SPCE061A的数据存储空间为的数据存储空间为2K字。字。222. 子程序的递归子程序的递归 递归调用是指子程序递归调用是指子程序调用子程序本身调用子程序本身。 进行递归调用需注意的是:一个递归程序进行递归调用需注意的是:一个递归程序必须有一个能够必须有一个能够退出递归调用的测试语句退出递归调用的测试语句。如果无条件地进行递归调用,。如果无条件地进行递归调用,会使堆栈空间溢出,导致严重错误。会使堆栈空间溢出,导致严重错误。23函数调用协议 所谓调用协议,指不同的子程序代码之间形成的一种握手通讯接口,并完成一个子程序到另外一个子程序的参数传递和控制,以及定义出子程序调用与子程序返回值的规则。24 调用协议包

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论