汇编语言5-2007_第1页
汇编语言5-2007_第2页
汇编语言5-2007_第3页
汇编语言5-2007_第4页
汇编语言5-2007_第5页
已阅读5页,还剩46页未读 继续免费阅读

下载本文档

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

文档简介

1、第5章 子程序设计5.1.1子程序设计基本概念把功能相对独立的程序段单独编写和把功能相对独立的程序段单独编写和调试,作为一个相对独立的模块供程调试,作为一个相对独立的模块供程序调用,就形成子程序序调用,就形成子程序子程序可以实现源程序的模块化,可子程序可以实现源程序的模块化,可简化源程序结构,可以提高编程效率简化源程序结构,可以提高编程效率子程序设计要利用过程定义伪指令参数传递是子程序设计的重点和难点子程序可以嵌套、递归5.1.2 子程序的定义与说明过程名过程名 procproc near|far near|far.过程名过程名 endpendp过程名过程名(子程序名)为符合语法的标识符(子程

2、序名)为符合语法的标识符nNEARNEAR属性(段内近调用)的过程只能被相同代属性(段内近调用)的过程只能被相同代码段的其他程序调用码段的其他程序调用nFARFAR属性(段间远调用)的过程可以被相同或不属性(段间远调用)的过程可以被相同或不同代码段的程序调用同代码段的程序调用对对简化段定义格式简化段定义格式,在微型、小型和紧凑存,在微型、小型和紧凑存储模式下,过程的缺省属性为储模式下,过程的缺省属性为nearnear; 在中型、大型和巨型存储模式下,过程的在中型、大型和巨型存储模式下,过程的缺省属性为缺省属性为farfar对对完整段定义格式完整段定义格式,过程的缺省属性为,过程的缺省属性为ne

3、arnear用户可以在过程定义时用用户可以在过程定义时用nearnear或或farfar改变缺改变缺省属性省属性子程序的常见格式subname proc ;具有缺省属性的具有缺省属性的subname过程过程push ax;保护寄存器保护寄存器:顺序压入堆栈:顺序压入堆栈push bx;ax/bx/cx仅是示例仅是示例push cx;过程体过程体pop cx;恢复寄存器恢复寄存器:逆序弹出堆栈:逆序弹出堆栈pop bxpop axret;过程返回过程返回subname endp;过程结束过程结束第5章CSIPCSIPAXBXCXCSIPSPSPSPSPSPCALL之前CALL之后现场保护以后现场

4、恢复以后RET以后程序执行过程中,堆栈变化示意图程序执行过程中,堆栈变化示意图; ;子程序功能:实现光标回车换行子程序功能:实现光标回车换行dpcrlfdpcrlfproc farproc far; ;过程开始过程开始push axpush ax; ;保护寄存器保护寄存器AXAX和和DXDXpush dxpush dxmov dl,mov dl,0dh0dh; ;显示显示“回车回车”mov ah,2mov ah,2int 21hint 21hmov dl,mov dl,0ah0ah; ;显示显示“换行换行”mov ah,2mov ah,2int 21hint 21hpop dxpop dx;

5、;恢复寄存器恢复寄存器DXDX和和AXAXpop axpop axretret; ;子程序返回子程序返回dpcrlfdpcrlfendpendp; ;过程结束过程结束ALdispALdispproc farproc farpush axpush ax; ;过程中使用了过程中使用了AXAX、CXCX和和DXDXpush cxpush cxpush dxpush dxpush axpush ax; ;暂存暂存axaxmov dl,almov dl,al; ;转换转换alal的高的高4 4位位mov cl,4mov cl,4shr dl,clshr dl,clor dl,30hor dl,30h;a

6、l;al高高4 4位变成位变成3 3cmp dl,39hcmp dl,39hjbe aldisp1jbe aldisp1add dl,7add dl,7; ;是是0Ah0Ah0Fh0Fh,还要加上,还要加上7 7aldisp1:aldisp1: mov ah,2mov ah,2; ;显示显示int 21hint 21hpop dxpop dx ; ;恢复原恢复原axax值到值到dxdxand dl,0fhand dl,0fh ; ;转换转换alal的低的低4 4位位or dl,30hor dl,30hcmp dl,39hcmp dl,39hjbe aldisp2jbe aldisp2add d

7、l,7add dl,7aldisp2:aldisp2: mov ah,2mov ah,2 ; ;显示显示int 21hint 21hpop dxpop dxpop cxpop cxpop axpop axretret ; ;过程返回过程返回ALdispALdispendpendp5.2 子程序设计方法在设计子程序时,需要考虑的问题是:在设计子程序时,需要考虑的问题是: 1、主程序调用子程序,子程序运行结束后返、主程序调用子程序,子程序运行结束后返回主程序回主程序 2、主程序如何把数据(参数)传送给子程序、主程序如何把数据(参数)传送给子程序 子程序如何把加工结果(参数)传送给主程子程序如何把加

8、工结果(参数)传送给主程序序5.2.1 子程序的调用与返回子程序是完成特定功能的一段程序子程序是完成特定功能的一段程序当主程序(调用程序)需要执行这个当主程序(调用程序)需要执行这个功能时,采用功能时,采用CALL调用指令转移到调用指令转移到该子程序的起始处执行该子程序的起始处执行当运行完子程序功能后,采用当运行完子程序功能后,采用RET返返回指令回到主程序继续执行回指令回到主程序继续执行主程序与子程序CALL label主程序主程序RET子程序子程序回到回到CALL指令后的指令指令后的指令处处返回地址返回地址 子程序调用指令CALL指令分成指令分成4种类型(类似种类型(类似JMP)CALL

9、label;段内调用、直接寻址;段内调用、直接寻址CALL r16/m16;段内调用、间接寻址;段内调用、间接寻址CALL far ptr label ;段间调用、直接寻址;段间调用、直接寻址CALL far ptr mem ;段间调用、间接寻址;段间调用、间接寻址CALL指令需要保存返回地址:指令需要保存返回地址:n段内调用段内调用入栈偏移地址入栈偏移地址IPSPSP2, SS:SP、SP+1 IPn段间调用段间调用入栈偏移地址入栈偏移地址IP和段地址和段地址CSSPSP2, SS:SP、SP+1 CSSPSP2, SS:SP、SP+1 IP子程序返回指令根据段内和段间、有无参数,分成根据段

10、内和段间、有无参数,分成4种类型种类型RET;无参数段内返回;无参数段内返回RET i16;有参数段内返回;有参数段内返回RET;无参数段间返回;无参数段间返回RET i16;有参数段间返回;有参数段间返回需要弹出需要弹出CALL指令压入堆栈的返回地址指令压入堆栈的返回地址n段内返回段内返回出栈偏移地址出栈偏移地址IPIPSS:SP、SP+1 , SPSP2n段间返回段间返回出栈偏移地址出栈偏移地址IP和段地址和段地址CSIPSS:SP、SP+1 ,SPSP2CSSS:SP、SP+1, SPSP2i16参数的作用参数的作用返回指令RET的参数RET i16;有参数返回;有参数返回RET指令可以

11、带有一个立即数指令可以带有一个立即数 i16 ,则堆栈指针则堆栈指针SP将增加将增加 i16 ,即,即SPSP+i16这个特点使得程序可以方便地废除若这个特点使得程序可以方便地废除若干执行干执行CALL指令以前入栈的参数指令以前入栈的参数通常利用堆栈保护现场通常利用堆栈保护现场,通过压栈通过压栈(push)指令将会在子程序中破坏的寄指令将会在子程序中破坏的寄存器内容、内存单元等压栈保存;存器内容、内存单元等压栈保存;而在返回原断点之前,通过弹出而在返回原断点之前,通过弹出(pop)指令恢复寄存器或内存单元)指令恢复寄存器或内存单元的内容。的内容。5.2.2 现场保护与恢复5.2.2 现场保护与

12、恢复(1)压栈和弹出时机)压栈和弹出时机压栈和弹出操作不宜在主程序中进行,一般在子程压栈和弹出操作不宜在主程序中进行,一般在子程序的开始处压栈保护,在序的开始处压栈保护,在RET指令之前弹出恢复指令之前弹出恢复。(2)压栈和弹出顺序)压栈和弹出顺序注意注意“先进后出先进后出”(3)压栈保护的内容)压栈保护的内容寄存器、内存单元、标志寄存器寄存器、内存单元、标志寄存器5.2.3 子程序的参数传递入口参数入口参数(输入参数):主程序提供(输入参数):主程序提供给子程序给子程序出口参数出口参数(输出参数):子程序返回(输出参数):子程序返回给主程序给主程序参数的形式:参数的形式: 数据本身(传值)数

13、据本身(传值) 数据的地址(传址)数据的地址(传址)传递的方法:传递的方法: 寄存器寄存器 内存变量内存变量 堆栈堆栈子程序计算数组元素的子程序计算数组元素的“校验和校验和”“校验和校验和”是指不记进位的累加是指不记进位的累加入口参数入口参数:数组的逻辑地址(传址)数组的逻辑地址(传址)元素个数(传值)元素个数(传值)出口参数出口参数:求和结果(传值)求和结果(传值)把参数存于约定的寄存器中,可以传把参数存于约定的寄存器中,可以传值,也可以传址。值,也可以传址。子程序对带有出口参数的寄存器不能子程序对带有出口参数的寄存器不能保护和恢复(主程序视具体情况进行保护和恢复(主程序视具体情况进行保护)

14、保护)子程序对带有入口参数的寄存器可以子程序对带有入口参数的寄存器可以保护,也可以不保护;但最好一致保护,也可以不保护;但最好一致入口参数:入口参数:CX元素个数,元素个数,DS:BX数组的段地址:偏移地址数组的段地址:偏移地址出口参数:出口参数:AL校验和校验和用寄存器传递参数.startup.startup ; ;设置入口参数(含有设置入口参数(含有DSDS数组的段地址)数组的段地址)mov mov bxbx,offset array,offset array ;BX;BX数组的偏移地址数组的偏移地址mov mov cxcx,count,count ;CX;CX数组的元素个数数组的元素个数

15、call checksumacall checksuma ; ;调用求和过程调用求和过程mov result,mov result,alal ; ;处理出口参数处理出口参数.exit 0.exit 0checksumachecksumaproc farproc farxor al,alxor al,al; ;累加器清累加器清0 0suma:suma:add add alal, ,bxbx ; ;求和求和inc bxinc bx; ;指向下一个字节指向下一个字节looploop suma sumaretretchecksumachecksumaendpendpendend主程序和子程序直接采用同

16、一个变量主程序和子程序直接采用同一个变量名共享同一个变量,实现参数的传递名共享同一个变量,实现参数的传递不同模块间共享时,需要声明不同模块间共享时,需要声明入口参数:入口参数:count元素个数,元素个数,array数组名(含段地址:偏移地址)数组名(含段地址:偏移地址)出口参数:出口参数:result校验和校验和用变量传递参数 .startup.startup ; ;设置入口参数(含有设置入口参数(含有DSDS数组的段地址)数组的段地址)mov bx,offset mov bx,offset arrayarray ;BX;BX数组的偏移地址数组的偏移地址mov cx,mov cx,count

17、count ;CX;CX数组的元素个数数组的元素个数call checksumacall checksuma ; ;调用求和过程调用求和过程mov result,almov result,al ; ;处理出口参数处理出口参数.exit 0.exit 0; ;子程序子程序Checksumb proc farChecksumb proc farpush axpush axpush bxpush bxpush cxpush cxxor al,alxor al,al ; ;累加器清累加器清0 0mov bx,offsetmov bx,offset array array ;BX;BX数组的偏移地址数组

18、的偏移地址mov cx,mov cx,countcount ;CX;CX数组的元素个数数组的元素个数sumb:sumb:add al,bxadd al,bx ; ;求和求和inc bxinc bxloop sumbloop sumbmov mov resultresult,al,al ; ;保存校验和保存校验和pop cxpop cxpop bxpop bxpop axpop axretretchecksumbchecksumbendpendp主程序将子程序的入口参数压入堆栈,主程序将子程序的入口参数压入堆栈,子程序从堆栈中取出参数子程序从堆栈中取出参数子程序将出口参数压入堆栈,主程序子程序将

19、出口参数压入堆栈,主程序弹出堆栈取得它们弹出堆栈取得它们入口参数:入口参数:顺序压入偏移地址和元素个数顺序压入偏移地址和元素个数出口参数:出口参数:AL校验和校验和用堆栈传递参数.startup.startupmov ax,offset arraymov ax,offset arraypush axpush axmov ax,countmov ax,countpush axpush axcall checksumccall checksumcadd sp,4 add sp,4 ;因为前面已经压了两次堆栈;因为前面已经压了两次堆栈mov result,almov result,al.exit 0

20、.exit 0图示图示 要注意堆栈的分配情况,保证参数存取正要注意堆栈的分配情况,保证参数存取正确、子程序正确返回,并保持堆栈平衡确、子程序正确返回,并保持堆栈平衡checksumcchecksumcproc nearproc nearpush bppush bpmov bp,spmov bp,sp; ;利用利用BPBP间接寻址存取参数间接寻址存取参数push bxpush bxpush cxpush cxmov bx,bp+6mov bx,bp+6 ;SS:BP+6;SS:BP+6指向偏移地址指向偏移地址mov cx,bp+4mov cx,bp+4 ;SS:BP+4;SS:BP+4指向元素个

21、数指向元素个数xor al,alxor al,alsumc:sumc:add add alal,bx ,bx inc bxinc bxloop sumcloop sumcpop cxpop cxpop bxpop bxpop bppop bpretretchecksumcchecksumcendpendp图示图示主程序BeginCall inputCall str2binCall bin2strCall hex2strCall out_strRet子程序InputRet: 输入十进制数字子程序Str2bin:合法性判断,如不合法,显示提示Ret: 信息,结束。否则转换为等值二进制数。子程序bi

22、n2strRet: 转换为16个二进制ASCII码子程序hex2strRet:转换为4个十六进制ASCII码子程序Out_strRet: 显示十进制、二进制、十六进制数字符stack segment stack dw 200h dup(0);堆栈段堆栈段stack endsdata segment in_buf db 6 in_leng db ? dec_buf db 6 dup(32),=;32为空格的为空格的ASCII码码 bin_buf db 16 dup(30h),B=;30H为为0的的ASCII hex_buf db 4 dup(?),H crlf db 13,10,$ mess_1

23、 db Please input a number(065535):$ mess_2 db Input invalid ,exit!,13,10,$data endscode segment assume cs:code,ds:data,ss:stackmain proc far push ds xor ax,ax push ax mov ax,data mov ds,ax;设置数据段;设置数据段 call input;输入数字串;输入数字串 mov bx,offset dec_buf add bl,in_leng adc bh,0;去掉出入串中回车符;去掉出入串中回车符 mov byte p

24、trbx,20h;否则回车覆盖已显示字符;否则回车覆盖已显示字符 call str2bin;将数字串变成机器内二进制数将数字串变成机器内二进制数 jc exit_no call bin2str;二进制数变成相应字符串;二进制数变成相应字符串call hex2str;十六进制变成相应字符串;十六进制变成相应字符串mov dx,offset crlfcall out_str;输出回车、换行,使显示更清晰;输出回车、换行,使显示更清晰mov dx,offset dec_bufcall out_str;输出结果表达式;输出结果表达式jmp exitexit_no: mov dx,offset crlf

25、;输出回车、换行,使显示更清晰;输出回车、换行,使显示更清晰call out_strmov dx,offset mess_2;显示;显示“输入无效输入无效”,退出,退出“提示字符提示字符串串”call out_strexit: retmain endpinput proc near mov dx,offset mess_1 mov ah,9 int 21h;显示输入的提示信息;显示输入的提示信息 mov dx,offset in_buf mov ah,0ah;10号功能调用号功能调用 int 21h;从键盘输入字符串到缓冲区;从键盘输入字符串到缓冲区in_buf retinput endpst

26、r2bin proc near sub ax,ax mov si,10 sub ch,ch mov cl,in_leng;in_leng为键盘缓冲区实际输入的字符个数为键盘缓冲区实际输入的字符个数 mov di,offset dec_bufloop_10: mov bl,di cmp bl,39h ja quit_n;39H,非十进制数字字符,非十进制数字字符 cmp bl,30h jb quit_n;9,加加7转换为转换为ASCII码码next_30: mov si,al inc si;存入缓冲区存入缓冲区 dec ch jnz loop_30 rethex2str endpout_str

27、proc near mov ah,09h int 21h retout_str endpcode endsend main5.3 子程序的嵌套调用与递归调用子程序内包含有子程序子程序内包含有子程序的调用就是子程序嵌套的调用就是子程序嵌套没有什么特殊要求没有什么特殊要求主程序BeginCall inputCall statistCall ouptut ret子程序InputCall out_strRet子程序StatistCall isleterCall isdigitRet子程序InputCall out_strRet子程序Out_strret子程序isleterret子程序isdigitre

28、t子程序Out_cutretstack segment stack dw 200h dup(0)stack ends data segmentin_buf db 80;键盘缓冲区键盘缓冲区in_leng db ?string db 80 dup(32)crlf db 13,10,$mess_1 dbPlease input a string(39h,非十进制数字字符非十进制数字字符 ja quit_n1 cmp al,30h;30H非十进制数字字符非十进制数字字符 jb quit_n1 stc;是数字字符是数字字符 retquit_n1: clc;不是数字字符不是数字字符 retisdigit endpisleter proc cmp al,A jb quit_n2;AL=AL=A,是大写字母,是大写字母 cmp al,a jb quit_n2;A

温馨提示

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

评论

0/150

提交评论