编辑: 哎呦为公主坟 | 2019-07-18 |
第六章 子程序结构 §6.
1 子程序的设计方法§6.2 嵌套与递归子程序§6.3 子程序举例§6.4 DOS系统功能调用 §6.1 子程序的设计方法
一、子程序指令
二、子程序的调用与返回
三、现场的保护与恢复
四、子程序参数的传递
一、子程序指令 子程序是完成特定功能的一段程序当主程序(调用程序)需要执行这个功能时,采用CALL调用指令转移到该子程序的起始处执行当运行完子程序功能后,采用RET返回指令回到主程序继续执行
一、子程序指令―调用指令 CALL指令分成4种类型(类似JMP)CALL label;
段内调用、直接寻址CALL r16/m16;
段内调用、间接寻址CALL far ptr label;
段间调用、直接寻址CALL far ptr mem;
段间调用、间接寻址CALL指令需要保存返回地址:段内调用――入栈偏移地址IPSP←SP-2,SS:[SP]←IP段间调用――入栈偏移地址IP和段地址CSSP←SP-2,SS:[SP]←CSSP←SP-2,SS:[SP]←IP
一、子程序指令―返回指令 根据段内和段间、有无参数,分成4种类型RET;
无参数段内返回RET i16;
有参数段内返回RET;
无参数段间返回RET i16;
有参数段间返回需要弹出CALL指令压入堆栈的返回地址段内返回――出栈偏移地址IPIP←SS:[SP], SP←SP+2段间返回――出栈偏移地址IP和段地址CSIP←SS:[SP],SP←SP+2CS←SS:[SP],SP←SP+2
一、子程序指令―返回指令RET的参数 RET i16;
有参数返回RET指令可以带有一个立即数i16,完成RET操作后,堆栈指针SP将增加,即SP←SP+i16这个特点使得程序可以方便地废除若干执行CALL指令以前入栈的参数
二、子程序的调用与返回 CALL label 主程序 RET 子程序 回到CALL指令后的指令处――返回地址
二、子程序的调用与返回―书写形式(同一代码段内)
二、子程序的调用与返回―书写形式(不同代码段)
三、现场的保护与恢复 现场:主程序转向子程序之前,其所使用的一些资源的状态(如标志位、R/M等)子程序与主程序分别编制,通常会导致使用的资源发生冲突而影响主程序在调用子程序之后的正确执行方法:利用堆栈在主程序中进行在子程序中进行
三、现场的保护与恢复―在主程序中进行 ……PUSH BXPUSH AXCALL SUB1POP AXPOP BX…… 注意:进栈/出栈的顺序 保护与恢复的对象:主程序用到的存有数据、中间结果且在CALL指令后还要用到的R/M
三、现场的保护与恢复―在子程序中进行 SUB1 PROCPUSH BXPUSH AX……POP AXPOP BXRETSUB1 ENDP 注意:进栈/出栈的顺序 保护与恢复的对象:子程序用到的R/M
四、子程序参数的传递 入口参数(输入参数):主程序提供给子程序出口参数(输出参数):子程序返回给主程序参数的形式:① 数据本身(传值)② 数据的地址(传址)传递的方法:① 寄存器 ② 变量 ③ 堆栈
四、子程序参数的传递 通过寄存器传送参数例6.3十进制到到十六进制转换程序.程序要求从键盘取得一个十进制数,然后把该数以十六进制的形式显示出来.
四、子程序参数的传递 Decihex segment assume cs:decihexMain proc farRepeat :call decibin call crlf call binihex call crlf jmp repeatMain endp Decihex ends end main
四、子程序参数的传递 Decibin proc near mov bx,0 newchar:mov ah,1 int 21h sub al,30h jl exit cmp al,9d jg exit cbw xchg ax,bx mov cx,10d mul cx xchg ax,bx add bx,ax jmp newcharExit: retDecibin endp
四、子程序参数的传递 Binhex proc near mov ch,4 rotate:mov cl,4 rol bx,cl mov al,bl and al,0fh add al,30h cmp al,3ah jl printit add al,7h printit: mov dl,al mov ah,2 int 21h dec ch jnz rotate ret binihex endp