版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1§6子程序结构一、过程定义伪操作二、子程序的调用与返回三、子程序参数的传递四、子程序嵌套递归重入2一、过程定义伪操作过程名 proc[near|far] ...过程名 endpNEAR属性(段内近调用)的过程只能被相同代码段的其他程序调用FAR属性(段间远调用)的过程可以被相同或不同代码段的程序调用对完整段定义格式,过程的缺省属性为near用户可以在过程定义时用near或far改变缺省属性对简化段定义格式:
在微型、小型和紧凑存储模式下,过程的缺省属性为near;在中型、大型和巨型存储模式下,过程的缺省属性为far
3codesegment
mainprocfar......
callsubr1......retmainendpsubr1procnear......retsubr1endpcodeendscodesegment
mainprocfar......callsubr1......retsubr1procnear......retsubr1endpmainendpcodeends例调用程序和子程序在同一代码段中4例调用程序和子程序不在同一代码段中
segxsegmentsubtprocfar......retsubtendp......
callsubt......segxendssegysegment......
callsubt......segyends5二、子程序的调用与返回段内近调用与返回段间远调用与返回CALLlabel主程序RET子程序回到CALL指令后的指令处——返回地址注意:CALL与RET指令
P98---P1006
子程序调用(中断调用):隐含使用堆栈保存返回地址callnearptrsubp
(1)保存返回地址PUSHIP
(2)转子程序
(IP)←subp的偏移地址callfarptrsubp
(1)保存返回地址PUSHCSPUSHIP
(2)转子程序
(CS)←subp的段地址
(IP)←subp的偏移地址
(IP)(SP)→
(IP)(SP)→
(CS)子程序的调用和返回7
RET返回指令段内返回:RET执行操作:(IP)←((SP)+1,(SP))(SP)←(SP)+2;段内带立即数返回:RETEXP段间返回:RET执行操作:(IP)←((SP)+1,(SP))(SP)←(SP)+2(CS)←((SP)+1,(SP))(SP)←(SP)+2;段间带立即数返回:RETEXP8子程序规范一个完整的子程序,特别是供其他编程人员使用的子程序,必须附有一个详细说明:子程序名(过程名)子程序功能介绍子程序的入口参数子程序的出口参数子程序内使用的寄存器(存储单元)使用该子程序的范例子程序名:DTOB功能:完成两位十进制数转换成二进制数入口参数:AL存放待转换的两位BCD码出口参数:CL存放转换后的二进制数占用寄存器:BX示例:输入AL=01010110B(56H)输出CL=00111000B(38H)某子程序的说明9子程序的常见格式;子程序说明Subnamproc ;具有缺省属性的subname过程
pushax ;保护寄存器:顺序压入堆栈
pushbx ;ax/bx/cx仅是示例
pushcx
…
;过程体
popcx ;恢复寄存器:逆序弹出堆栈
popbx popax
ret ;过程返回Subnamendp ;过程结束保护现场恢复现场10
一般,子程序中用到的寄存器应保存。如果使用的寄存器是用来在主–––子程序之间传送参数或回送结果,则不应该保存。11三、子程序参数的传递同一模块中的不同过程之间的参数传递多个模块之间的参数传递12同一模块中的不同过程之间的参数传递
通过寄存器传送参数直接访问模块中的变量通过地址表传送参数地址通过堆栈传送参数或参数地址13直接访问模块中的变量
L6-4.ASM通过地址表传送参数地址
L6-4-1.ASM通过堆栈传送参数或参数地址
L6-4-2.ASM通过寄存器传送参数
L6-3.ASM14例6.3十进制到十六进制的转换程序(通过寄存器传送变量)decihexsegment;1016assumecs:decihexmainprocfar
pushdssubax,axpushaxrepeat:calldecibin;102
callcrlf
callbinihex;216
callcrlfjmprepeatretmainendp15decibinprocnear;102movbx,0newchar:movah,1int21hsubal,30hjlexit;<0退出
cmpal,9djgexit;>9退出
cbwxchgax,bxmovcx,10dmulcxxchgax,bxaddbx,axjmpnewcharexit:retdecibinendp16binihexprocnear;216movch,4rotate:movcl,4rolbx,clmoval,blandal,0fhaddal,30hcmpal,3ahjlprintitaddal,7h;‘A’~’F’printit:movdl,almovah,2int21hdecchjnzrotateretbinihexendp17crlfprocnearmovdl,0dhmovah,2int21hmovdl,0ahmovah,2int21hretcrlfendpdecihexendsendmain18例6.4累加数组中的元素(直接访问模块中的变量)datasegmentarydw1,2,3,4,5,6,7,8,9,10countdw10sumdw?dataendscodesegmentmainprocfarassumecs:code,ds:datastart:pushdssubax,axpushaxmovax,datamovds,axcallnearptrproaddretmainendp19proaddprocnearpushaxpushcxpushsi
leasi,arymovcx,countxorax,axnext:addax,[si]addsi,2loopnextmovsum,axpopsipopcxpopaxretproaddendpcodeendsendstart20datasegmentarydw1,2,3,4,5,6,7,8,9,10countdw10sumdw?ary1dw10,20,30,40,50,60,70,80,90,100count1dw10sum1dw?dataends如果数据段定义如下:*如果直接访问内存变量,那么累加数组ary和数组ary1中的元素不能用同一个子程序proadd21例6.4累加数组中的元素(通过地址表传送变量地址)datasegmentarydw10,20,30,40,50,60,70,80,90,100countdw10sumdw?
tabledw3dup(?);地址表dataendscodesegmentmainprocfarassumecs:code,ds:datastart:pushdssubax,axpushaxmovax,datamovds,ax
movtable,offsetarymovtable+2,offsetcountmovtable+4,offsetsummovbx,offsettablecallproaddretmainendp22proaddprocnear
pushaxpushcxpushsipushdi
movsi,[bx]movdi,[bx+2]movcx,[di]movdi,[bx+4]
xorax,axnext:addax,[si]addsi,2loopnext
mov[di],ax
popdipopsipopcxpopax
retproaddendpcodeendsendstart
ary
100000
200002
30
40
50
60
70
80
90
100
count
100014
sum
?0016
table
00000018(bx)00140016(si)(di)23例6.4累加数组中的元素(通过堆栈传送变量地址)datasegmentarydw10,20,30,40,50,60,70,80,90,100countdw10sumdw?dataendsstacksegmentdw100dup(?)toslabelwordstackends
24code1segmentmainprocfarassumecs:code1,ds:data,ss:stackstart:
movax,stackmovss,axmovsp,offsettospushdssubax,axpushaxmovax,datamovds,ax
movbx,offsetarypushbxmovbx,offsetcountpushbxmovbx,offsetsumpushbxcallfarptrproaddretmainendpcode1ends25code2segmentassumecs:code2proaddprocfar
pushbpmovbp,sp
pushaxpushcxpushsipushdi
movsi,[bp+0ah]movdi,[bp+8]movcx,[di]movdi,[bp+6]
(bp)+0a
0000
(sp)
(di)
(si)
(cx)
(ax)
(bp)(bp)
(ip)
(cs)
(bp)+60016
(bp)+8
0014
0
(ds)
xorax,axnext:addax,[si]addsi,2loopnext
mov[di],ax
popdi
popsipopcxpopax
popbp
ret6proaddendpcode2endsendstart26求LBC6-2.ASM27CODESEGMENTASSUMECS:CODE,DS:DATAMAINPROCFARSTART: MOVAX,DATA MOVDS,AX MOVAX,X MOVPIN,AX
CALLSQROOT MOVCX,ROOT MOVAX,Y MOVPIN,AX
CALLSQROOT MOVAX,ROOT ADDAX,CX MOVSUM,AX
MOVAH,4CH INT21HMAINENDPSQROOTPROCNEAR MOVDX,PIN XORAX,AX ANDDX,DX JZSQR2SQR1:MOVBX,AX SHLBX,1 INCBX SUBDX,BX JCSQR2 INCAX JMPSQR1SQR2:MOVROOT,AX
RETSQROOTENDPCODEENDS ENDSTART28多个模块之间的参数传递使用COMMON共用数据块
LBC6-4.ASM+L6PROADD.ASM2.使用PUBLIC和EXTRN(1).LB6-4.ASM+PROADD.ASM(2).EXP1.ASM+EXP22.ASM;near(3).EXP11.ASM+EXP21.ASM;far3.C调用汇编参见:汇编语言与C/C++的混合编程.PPTEXP3.C+EXP31.ASM步骤:A.masmexp31B.tcc–ms–cexp3C.tlink/3lib\c0sexp3exp31,exp3,,lib\cs29多个模块之间的参数传递1.
修改L6-4.ASM(1).LB6-4.ASM+L6PROADD.ASM(2).LBC6-4.ASM+PROADD.ASM30extrnproadd:farpublicary,count,sumdatasegmentarydw10dup(2)countdw10sumdw?dataendscodesegmentmainprocfarassumecs:code,ds:datastart:pushdssubax,axpushaxcallfarptrproaddretmainendpcodeendsendmainpublicproaddextrnary:word,count:word,sum:wordcodesegmentproaddprocfarassumecs:code
pushax
pushcx
pushsi
movax.segarymoves,axleasi,es:arymovcx,es:countxorax,axnext:addax,[si]addsi,2loopnextmoves:sum,ax
popsipopcxpopaxretproaddendpcodeendsendLB6-4.asmL6PROADD.ASM31extrnproadd:fardatasegmentcommonarydw10dup(2)countdw10sumdw?dataendscodesegment;publicmainprocfarassumecs:code,ds:datastart:pushdssubax,axpushaxcallfarptrproadd;nearretmainendpcodeendsendmainpublicproadddatasegmentcommonarydw10dup(?)countdw10sumdw?dataendscodesegment;public
proaddprocfarassumecs:code,ds:data
pushaxmovax,datamovds,ax
pushcx
pushsileasi,arymovcx,countxorax,axnext:addax,[si]addsi,2loopnextmovsum,ax
popsipopcxpopaxretproaddendpcodeendsendLBC6-4.asmPROADD.ASM32多个模块之间的参数传递2.EXP1.ASM+EXP22.ASM;near3.EXP11.ASM+EXP21.ASM;far4.C调用汇编
EXP3.C+EXP31.ASM33extrndisp_string:nearstacksegmentparastackdw100hdup(?)toslabelwordstackendsdatasegmentparapublicstring1db'teststring1',0dh,0ah,'$'publicstring1dataendscodesegmentparapublicassumeds:data,cs:code,ss:stackmainprocfarmovax,stackmovss,axmovsp,offsettosmovax,datamovds,ax
calldisp_stringmovah,4chint21hmainendpcodeendsendmainpublicdisp_string:nearextrnstring1:bytecodesegmentparapublicassumecs:codedisp_stringprocnearmovdx,offsetstring1movah,09hint21hretdisp_stringendpcodeendsendEXP22.ASMEXP1.ASM生成EXP1.MAP34extrndisp_string:fardatasegmentstring1db'teststring1',0dh,0ah,'$'
publicstring1dataendscodesegmentassumeds:data,cs:codemainprocfarmovax,datamovds,ax
callfarptrdisp_stringmovah,4chint21hmainendpcodeendsendmain
publicdisp_string
extrnstring1:bytecodesegmentassumecs:codedisp_stringprocfarmovdx,offsetstring1movah,09hint21hretdisp_stringendpcodeendsendEXP21.ASMEXP11.ASM生成EXP11.MAP35externintdisp(char*);main(){charstring2[20]={"teststring2$"};
disp(string2);}public_disp.modelsmall.code_dispproc
pushbpmovbp,spmovdx,[bp+4]
movah,09hint21hpopbpret_dispendpend4.C调用汇编
EXP3.C+EXP31.ASMEXP3.CEXP31.ASM36externintadd(int,int);main(){inta=100,b=200,c;
c=add(a,b);printf(“c=%d\n”,c);}public_add.modelsmall.code_addproc
pushbpmovbp,spmovax,[bp+4]
movbx,[bp+6]addax,bx
popbpret_addendpend4.C调用汇编
ADD3.C+ADD31.ASMADD3.CADD31.ASM37堆栈段200+6100+4偏移地址+2BP3839主程序
子程序A
子程序B
proc_A
proc_B…...………...
callproc_Acallproc_B
…...…………retret子程序的嵌套 子程序嵌套就是子程序内包含有子程序的调用,没有什么特殊要求四、子程序嵌套递归重入40当子程序直接或间接地嵌套调用自身时称为递归调用,含有递归调用的子程序称为递归子程序递归子程序必须采用寄存器或堆栈传递参数,递归深度受堆栈空间的限制子程序的递归例:求阶乘4142.modelsmall.stack256.data N dw3 result dw?.code.startup┇ movbx,N
pushbx
;入口参数:N
callfact
;调用递归子程序
popresult
;出口参数:N!
.exit0FACT.ASM43;计算N!的近过程;入口参数:压入N;出口参数:弹出N!factprocpushaxpushbpmovbp,sp;取入口参数N
movax,[bp+6]cmpax,0;N>0,N!=N×(N-1)!jnefact1;N=0,N!=1
incaxjmpfact2fact1:decax;N-1 pushax
callfact;调用递归子程序求(N-1)! popax
mulwordptr[bp+6];求N×(N-1)!fact2:mov[bp+6],ax;存入出口参数N! popbp popax retfact endp44递归子程序调用时进栈返回时出栈13!2!1!45例:将字符串反序输出REVER.ASM
movbx,offsetstrpushbx
callreverspopbxmovdl,[bx]movah,2int21hreversprocnear
pushaxpushbxpushdxpushbpmovbp,spmovbx,[bp+10]moval,[bx]cmpal,'$'jnere_calljmpreturnre_call:incbx
pushbx
callrevers
popbxmovdl,[bx]movah,2int21hreturn:
popbppopdxpopbxpopaxretreversendp46reversprocnear
pushaxpushbxpushdxpushbpmovbp,spmovbx,[bp+10]moval,[bx]cmpal,'$'jnere_calljmpreturnre_call:incbx
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 阅读教育理论心得体会
- 酒店三月个人工作总结
- 概率论公式总结30347
- 最美家风事迹材料7篇
- 福建省南安市2024−2025学年高二上学期第1次阶段考试(10月)数学试题含答案
- 我的理想是医生演讲稿5篇
- 2023年植物促生菌剂资金申请报告
- DB11T 1491-2017 街道(乡镇)、社区(村)人力资源和社会保障平台服务规范
- 2024基于GIS的测绘数据管理平台技术规范
- 上海市县(2024年-2025年小学五年级语文)统编版能力评测((上下)学期)试卷及答案
- 下肢动脉闭塞症的护理
- 腾讯游戏公司企业分析报告
- 微观经济学(第三版)课程标准
- 元代青花瓷工艺美术鉴赏课件
- 心脏骤停与猝死
- 小学二年级数学培优辅差工作记录文本
- 工程师职称代评销售话术
- 模具验收检查表
- 海洋生态文明建设知识讲座
- 私立民办初中学校项目融资计划书
- 脓毒性休克病人护理查房课件
评论
0/150
提交评论