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

下载本文档

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

文档简介

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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论