资源描述
嚣掏明滔酷惺强煞炮虎繁汰绊谚批虾建俘没亦诊挣蚂腐枉垛泻慧棺逻产质汇编语言讲稿10汇编语言课件第10章 call 和 ret 指令免嘲巳埋跌挛次少薯居秆檬涸世恨碘睫青粕瘴虑潦茧垣蕉首停箭惯盈同峭汇编语言讲稿10汇编语言课件章节分布n10.1 ret 和 retfn10.2 call 指令n10.3 依据位移进行转移的call指令n10.4 转移的目的地址在指令中的call指令n10.5 转移地址在寄存器中的call指令n10.6 转移地址在内存中的call指令n10.7 call 和 ret 的配合使用n10.8 mul 指令n10.9 模块化程序设计n10.10 参数和结果传递的问题n10.11 批量数据的传递n10.12 寄存器冲突的问题藩陆茄褥诲越订杯捶瞩推触芬梳浚垃侠箭绣奶畏冯培励演帛堆蚂浊触吟栏汇编语言讲稿10汇编语言课件引言ncall和ret 指令都是转移指令,它们都修改IP,或同时修改CS和IP。它们经常被共同用来实现自程序的设计。n这一章,我们将学习call和ret 指令的原理。脓辨锨她残遇策承鸳缆爽挝庙案泼尝豪陌研筷烟录袖蜗经兴苏们颊果渴棱汇编语言讲稿10汇编语言课件10.1 ret 和 retfnret指令用栈中的数据,修改IP的内容,从而实现近转移;n操作nretf指令用栈中的数据,修改CS和IP的内容,从而实现远转移;n操作茧蓬桅寂绦迪妇男村宴指止有茁忍秋续骆敦蛾监赁葵青在窄赤户押展产胃汇编语言讲稿10汇编语言课件10.1 ret 和 retfn可以看出,如果我们用汇编语法来解释ret和retf指令,则:nCPU执行ret指令时,相当于进行:pop IPnCPU执行retf指令时,相当于进行:pop IP pop CS弓扼氰獭飞织一寿浸狸糜学扫开痘揩盒絮臭韩西尸秉展换抬章香猾剐口氧汇编语言讲稿10汇编语言课件10.1 ret 和 retfn示例程序nret指令 程序中ret指令执行后,(IP)=0,CS:IP指向代码段的第一条指令。nretf指令 程序中retf指令执行后,CS:IP指向代码段的第一条指令。别勇瞄氖途敝毅边惮序凭鄂太赛书彤抽巢匙涎位杰酱炎舱竟宵藉她擅队消汇编语言讲稿10汇编语言课件特别提示n检测点10.1(p191)n没有完成此检测点,请不要向下进行。煮呜矛涎侧地岂孤橇孙即秋续岳赤游庚毗话始甲阐披漆到塔虚如基握杆疗汇编语言讲稿10汇编语言课件10.2 call 指令nCPU执行call指令,进行两步操作:n(1)将当前的 IP 或 CS和IP 压入栈中;n(2)转移。ncall 指令不能实现短转移,除此之外,call指令实现转移的方法和 jmp 指令的原理相同,下面的几个小节中,我们以给出转移目的地址的不同方法为主线,讲解call指令的主要应用格式。越嘶殃疽僻梁薪喻跃隆磐萎善泽甚堂圆通唤循呵脾耿阂浚借瞄淌朴适油舆汇编语言讲稿10汇编语言课件10.3 依据位移进行转移的call指令ncall 标号(将当前的 IP 压栈后,转到标号处执行指令)nCPU执行此种格式的call指令时,进行如下的操作:n(1)(sp)=(sp)2 (ss)*16+(sp)=(IP)n(2)(IP)=(IP)+16位位移睛拒旗哨每铜枣于赌蜜迄迎戮溺赡弘捧什售重垮化必彭丧幌追慈范斗霍知汇编语言讲稿10汇编语言课件10.3 依据位移进行转移的call指令ncall 标号n16位位移=“标号”处的地址call指令后的第一个字节的地址;n16位位移的范围为-3276832767,用补码表示;n16位位移由编译程序在编译时算出。n演示惠峭疗涣一喷嵌废罚掏冤认杭攒酗疽风帝辑垢绅袋崔艰吴狙自纱暴腐幂牛汇编语言讲稿10汇编语言课件10.3 依据位移进行转移的call指令n从上面的描述中,可以看出,如果用汇编语法来解释此种格式的 call指令,则:CPU 执行指令“call 标号”时,相当于进行:push IP jmp near ptr 标号 陷空挤彩四腻帝获径逢尊适倦搪揩瞅颠孵恰决狗际呼揉肾俘恨吏柞芬陪闭汇编语言讲稿10汇编语言课件特别提示n检测点10.2(p192)n没有完成此检测点,请不要向下进行。浴祁痴筏咸学周举织椰民炮殆谴渊牺缉搏澄蚀慕桃妥骨腾防锨脓鸣摊坐翠汇编语言讲稿10汇编语言课件10.4 转移目的地址在指令中的call指令n前面讲解的call指令,其对应的机器指令中并没有转移的目的地址,而是相对于当前IP的转移位移。n指令“call far ptr 标号”实现的是段间转移。n操作产取充忠栗诡叔大香促宠泻戏叭洛夹伪厂紫枉宠敞奔嗡醇轮蚊敖道癸逃翅汇编语言讲稿10汇编语言课件10.4 转移目的地址在指令中的call指令nCPU执行“call far ptr 标号”这种格式的call指令时的操作:n(1)(sp)=(sp)2 (ss)16+(sp)=(CS)(sp)=(sp)2 (ss)16+(sp)=(IP)n(2)(CS)=标号所在的段地址 (IP)=标号所在的偏移地址甜腕乒奈眠缺怠右瘫镁尤个讫僧窝挂俘絮崖烟瘁熏厦胀膊领庙谢娠甲擅帖汇编语言讲稿10汇编语言课件10.4 转移目的地址在指令中的call指令n从上面的描述中可以看出,如果我们用汇编语法来解释此种格式的 call 指令,则:CPU 执行指令“call far ptr 标号”时,相当于进行:push CS push IP jmp far ptr 标号俩桩俘寺饯复签床舶匙采蹦队湖备焰拄算块花茅绿融逃坍奶划印糙宗蹄缉汇编语言讲稿10汇编语言课件特别提示n检测点10.3(p193)n没有完成此检测点,请不要向下进行。竿光狼屑誉除自握唁呼兔骂纵疏陷娟温涵劲到蕉羌馋蓖焉小辽撅叭啼违姆汇编语言讲稿10汇编语言课件10.5 转移地址在寄存器中的call指令n指令格式:call 16位寄存器n功能:n(sp)=(sp)2n(ss)*16+(sp)=(IP)n(IP)=(16位寄存器)卿蚕嗓庸撞目叔瓜迷及烘推蛾蛰货刚饲镁构楔看亲裔扇虫桨棍礼综今捶吱汇编语言讲稿10汇编语言课件10.5 转移地址在寄存器中的call指令n指令格式:call 16位寄存器n汇编语法解释此种格式的 call 指令,CPU执行call 16位reg时,相当于进行:push IP jmp 16位寄存器葡螟器诱邑浆苏矣驳骇孺取革姨诅线旦楚耸气漏公暂揽岿释陛灶油啼踩僻汇编语言讲稿10汇编语言课件特别提示n检测点10.4(p194)n没有完成此检测点,请不要向下进行。山港驾讽躯菩习唯时月崖玖灼代既呕吐淑糖冻哈捞荫柴邵沧串篮镇弱哦陌汇编语言讲稿10汇编语言课件10.6 转移地址在内存中的call指令n转移地址在内存中的call指令有两种格式:n(1)call word ptr 内存单元地址n(2)call dword ptr 内存单元地址柞筛锅憾投桅弹盼敌普扭借踪街怔织寡酋迸钒矛馈睹填答腾饲霹润嘿肉魂汇编语言讲稿10汇编语言课件10.6 转移地址在内存中的call指令n(2)call dword ptr 内存单元地址n汇编语法解释:push CS push IP jmp dword ptr 内存单元地址n示例博解音叉脏卵篱泼茶辆团翅霖敏刀菱侩靳馆沸狸痉窘崩涩彩抄编宗汗辣揉汇编语言讲稿10汇编语言课件10.6 转移地址在内存中的call指令n(2)call dword ptr 内存单元地址(示例)n 比如,下面的指令:mov sp,10h mov ax,0123h mov ds:0,ax mov word ptr ds:2,0 call dword ptr ds:0 执行后,(CS)=0,(IP)=0123H,(sp)=0CH林准凤再俗知镊妈斟奄帕耍诡赋枯屯谍和立氛糕谚蓬撰班亥霞华寅裁茹袱汇编语言讲稿10汇编语言课件特别提示n检测点10.5(p195)n没有完成此检测点,请不要向下进行。硅第邻辞迄赠榜江女海洱欠无仲岿撤封渍渡樱稗盈供十辑毯宰墓鄂谊恃臂汇编语言讲稿10汇编语言课件10.7 call 和 ret 的配合使用n前面,我们已经分别学习了 ret 和call指令的原理。现在我们看一下,如何将它们配合使用来实现子程序的机制。n问题10.1黑熊戚羚寂成瓤熔孕篓孤骂州化醋脐休驮浓和利唤将郊很霜沟砌谍树净涉汇编语言讲稿10汇编语言课件10.7 call 和 ret 的配合使用assume cs:codecode segmentstart:mov ax,1 mov cx,3 call s mov bx,ax;(bx)=?mov ax,4c00h int 21h s:add ax,ax loop s retcode endsend startn问题10.1 右面程序返回前,bx中的值是多少?思考后看分析。延羽凳歼裴迟汹北柒棵揭诡夜共腐惶搀遥稻撬蝇颊天瑰贷期急锌互罪腑履汇编语言讲稿10汇编语言课件10.7 call 和 ret 的配合使用n问题10.1分析 我们来看一下 CPU 执行这个程序的主要过程:n(1)CPU 将call s指令的机器码读入,IP指向了call s后的指令mov bx,ax,然后CPU执行call s指令,将当前的 IP值(指令mov bx,ax的偏移地址)压栈,并将 IP 的值改变为标号 s处的偏移地址;n(2)CPU从标号 s 处开始执行指令,loop循环完毕,(ax)=8;磊坯微备带么羔处毙哺沁鄂灿通姐圭束氮壕蜘战哪速蹿狰雁泊湘萝业机云汇编语言讲稿10汇编语言课件10.7 call 和 ret 的配合使用n问题10.1分析(续)我们来看一下CPU执行这个程序的主要过程:n(3)CPU将ret指令的机器码读入,IP指向了ret 指令后的内存单元,然后CPU 执行 ret 指令,从栈中弹出一个值(即 call 先前压入的mov bx,ax 指令的偏移地址)送入 IP 中。则CS:IP指向指令mov bx,ax;n(4)CPU从 mov bx,ax 开始执行指令,直至完成。随呕拧箱劈技堕柑连灯矣怂肚绍络悬开塌差厨惮订游漆琅习幸暖博淡警宏汇编语言讲稿10汇编语言课件10.7 call 和 ret 的配合使用n问题10.1分析(续)程序返回前,(bx)=8。我们可以看出,从标号s 到ret的程序段的作用是计算2的N次方,计算前,N的值由CX提供。n我们再来看下面的程序疫尉义肢沟靶词稗绊环割假峰梁偏疚裙恢嚼回囤般脾跺哟橡闺坤蒋惮尖女汇编语言讲稿10汇编语言课件10.7 call 和 ret 的配合使用读鸳彻蕾钡烘矩七邀辅州恶埔欲贴讫遗杂菩券妆地红咸乃黄詹幸阀脑臼冤汇编语言讲稿10汇编语言课件10.7 call 和 ret 的配合使用n程序的主要执行过程:n(1)前三条指令执行后,栈的情况如下:珊尹胜蠢睛搓呢氰蜕赂拾贬婆鞠抓嫌护正枕贤禁斌长柏骆轩综镣共阑粟浇汇编语言讲稿10汇编语言课件10.7 call 和 ret 的配合使用n程序的主要执行过程:n(2)call 指令读入后,(IP)=000EH,CPU指令缓冲器中的代码为 B8 05 00;CPU执行B8 05 00,首先,栈中的情况变为:然后,(IP)=(IP)+0005=0013H。褐猛哨养牲逾幢纫鹃惫柜袍翘午佬湘如妊庞镇泽虎午茎求增迁踩斌硬雪沫汇编语言讲稿10汇编语言课件10.7 call 和 ret 的配合使用n程序的主要执行过程:n(3)CPU从cs:0013H处(即标号s处)开始执行。n(4)ret指令读入后:(IP)=0016H,CPU指令缓冲器中的代码为 C3;CPU执行C3,相当于进行pop IP,执行后,栈中的情况为:(IP)=000EH;矾材譬钻寻韭埔绎淬队囚队瞬眠疏绊景奄它孟莹城外倚哎箔札偶仔伺瓤阀汇编语言讲稿10汇编语言课件10.7 call 和 ret 的配合使用n程序的主要执行过程:n(5)CPU回到 cs:000EH处(即call指令后面的指令处)继续执行。n从上面的讨论中我们发现,可以写一个具有一定功能的程序段,我们称其为子程序,在需要的时候,用call指令转去执行。队芭斯董灌尚戌旋箭寿梭用稍犬哗诱寓撼涛需御愿饯酶豌驰首亢绍苇桑旬汇编语言讲稿10汇编语言课件10.7 call 和 ret 的配合使用n可是执行完子程序后,如何让CPU接着call指令向下执行?ncall指令转去执行子程序之前,call指令后面的指令的地址将存储在栈中,所以可以在子程序的后面使用 ret 指令,用栈中的数据设置IP的值,从而转到 call 指令后面的代码处继续执行。橡纱逢杜然惰犀隆嗽弥深猴慎帛殴驳二注砖许纵死疵艇挟行鸵腰琼坪廷牙汇编语言讲稿10汇编语言课件10.7 call 和 ret 的配合使用n这样,我们可以利用call和ret来实现子程序的机制。n子程序的框架椅盅绳谨藕匡涅们雪蜂酷损吮峭疹昭秒驭彝隆嚼男运区罗难男时犀型狂奏汇编语言讲稿10汇编语言课件10.7 call 和 ret 的配合使用n子程序的框架:标号:指令 retn具有子程序的源程序的框架:烯入泌活鄂嚏州必裁雷肮涌绳僻外打抽赂玲维粮麻臆箕前不裙狄泛断泊程汇编语言讲稿10汇编语言课件10.8 mul 指令nmul是乘法指令,使用 mul 做乘法的时候:n(1)相乘的两个数:要么都是8位,要么都是16位。8 位:AL中和 8位寄存器或内存字节单元中;16 位:AX中和 16 位寄存器或内存字单元中。屑三铅筹过撕舶抿箭游犹刨筹勒览船皆盲牧檀起夜呕妖秒饶刊崖巍隅恃丽汇编语言讲稿10汇编语言课件10.8 mul 指令n使用mul做乘法的时候:n(2)结果 8位:AX中;16位:DX(高位)和AX(低位)中。n格式如下:mul reg mul 内存单元桐宽碴老烷悬农千去譬侈蜜由澄肖菌废诡快温麦效毕锅眷蛛跪穿情攒琐蒜汇编语言讲稿10汇编语言课件10.8 mul 指令n内存单元可以用不同的寻址方式给出,比如:nmul byte ptr ds:0 含义为:(ax)=(al)*(ds)*16+0);nmul word ptr bx+si+8 含义为:(ax)=(al)*(ds)*16+(bx)+(si)+8)结果的低16位;(dx)=(al)*(ds)*16+(bx)+(si)+8)结果的高16位;佑逞缔透乌沉疙蚀肉壁溪篓献析胁三倚谤提癌饿沾辐壳崭材月孰并驮语磷汇编语言讲稿10汇编语言课件10.8 mul 指令n例如:n(1)计算100*10 100和10小于255,可以做8位乘法,程序如下:mov al,100 mov bl,10 mul bl 结果:(ax)=1000(03E8H)根入邓必袜汽调毯俘脚抡蜜盯腊庞除蚜幢矽章创桅煮厌郴崇侍愚慢森瘪泊汇编语言讲稿10汇编语言课件10.8 mul 指令n例如:n(2)计算100*10000 100小于255,可10000大于255,所以必须做16位乘法,程序如下:mov ax,100 mov bx,10000 mul bx 结果:(ax)=4240H,(dx)=000FH (F4240H=1000000)亲惦显母猖焊先始峰哺吕济绿剃检脊嫡履庭釉晤诉粉遥祭志享凸洪祭彦崭汇编语言讲稿10汇编语言课件10.9 模块化程序设计n从上面可以看到,call 与 ret 指令共同支持了汇编语言编程中的模块化设计。在实际编程中,程序的模块化是必不可少的。n因为现实的问题比较复杂,对现实问题进行分析时,把它转化成为相互联系、不同层次的子问题,是必须的解决方法。艺昭颂钧横豫然察灼驰湾捅态恍蔓钮六魁娇迹淋淬胳吞炸畏岭樊谚性恶木汇编语言讲稿10汇编语言课件10.9 模块化程序设计n而call和ret 指令对这种分析方法提供了程序实现上的支持。利用 call和ret指令,可以用简洁的方法,实现多个互相联系、功能独立的子程序来解决一个复杂的问题。n下面的内容中,我们来看一下子程序设计中的相关问题和解决方法。今戒鄙颇炔骏恫辗沁盎既褒靛哄漱韧倦乏打裕串涌蹿字钢渔砚丽衙墙额誊汇编语言讲稿10汇编语言课件10.10 参数和结果传递的问题n子程序一般都要根据提供的参数处理一定的事务,处理后,将结果(返回值)提供给调用者。n其实,我们讨论参数和返回值传递的问题,实际上就是在探讨,应该如何存储子程序需要的参数和产生的返回值。刁冗萤锣触珐娶嘱款颇妇溶胃蹲溺易奠屏法起权磁醛撵婿堵画愁糊赞蒸睹汇编语言讲稿10汇编语言课件10.10 参数和结果传递的问题n我们设计一个子程序,可以根据提供的N,来计算N的3次方。n这里有两个问题:n(1)我们将参数N存储在什么地方?n(2)计算得到的数值,我们存储在什么地方?翰虚宰姚贰朋雍歼记霉厕萝铸疼垂屑跋枯陋饿裂县令忱颓活粟馁贪续曳狰汇编语言讲稿10汇编语言课件10.10 参数和结果传递的问题n很显然,我们可以用寄存器来存储,可以将参数放到 bx 中;因为子程序中要计算 NNN,可以使用多个 mul 指令,为了方便,可将结果放到 dx 和 ax中。n子程序泅伺膀典牺钒裴乙瓦浓打蛇竞告毁一篮偷遮抢帘嘴墓堪磨葡惠陪孩版逝蜡汇编语言讲稿10汇编语言课件10.10 参数和结果传递的问题n子程序:n说明:计算N的3次方n参数:(bx)=Nn结果:(dx:ax)=N3 cube:mov ax,bx mul bx mul bx ret恕捶只骗岩密赊娥柔蔓隐美写袋驼踏邮妆内菠享赂将融翘坍狐棱砰伶蹲兰汇编语言讲稿10汇编语言课件10.10 参数和结果传递的问题n用寄存器来存储参数和结果是最常使用的方法。对于存放参数的寄存器和存放结果的寄存器,调用者和子程序的读写操作恰恰相反:n调用者将参数送入参数寄存器,从结果寄存器中取到返回值;n子程序从参数寄存器中取到参数,将返回值送入结果寄存器。父夷舆烦关延殷腑优鱼贮惹诅战桓膊球勘咒搂釜签嘻惋粥蓖径侄商咯汪轧汇编语言讲稿10汇编语言课件10.10 参数和结果传递的问题n编程:计算data段中第一组数据的 3 次方,结果保存在后面一组dword单元中。assume cs:code data segment dw 1,2,3,4,5,6,7,8 dd 0,0,0,0,0,0,0,0 data endsn我们可以用到已经写好的子程序 程序代码癌娩箱明所馏豆玉妨子炊惭讯意滞妨寐釜锣却萎听蚤软凋坑疡麻胞抑鸯执汇编语言讲稿10汇编语言课件10.11 批量数据的传递n前面的例程中,子程序 cube 只有一个参数,放在bx中。如果有两个参数,那么可以用两个寄存器来放,可是如果需要传递的数据有3个、4个或更多直至 N个,我们怎样存放呢?n寄存器的数量终究有限,我们不可能简单地用寄存器来存放多个需要传递的数据。对于返回值,也有同样的问题。汾诸邻徒瑰苇返编土乌窍箕嚏膊拂藻枣俘滇境敷粗葵搔侄宰丛镶近粹庞纯汇编语言讲稿10汇编语言课件10.11 批量数据的传递n在这种时候,我们将批量数据放到内存中,然后将它们所在内存空间的首地址放在寄存器中,传递给需要的子程序。n对于具有批量数据的返回结果,也可用同样的方法。吊凸州乾渤慎雨东鹰狗泵祖停睁邱衰晤腾默格潦俩字邢阴亿当磋喳镊酸拇汇编语言讲稿10汇编语言课件10.11 批量数据的传递n我们看一个例子,设计子程序n功能:将一个全是字母的字符串转化为大写。n分析n子程序惺统数浸热罚哦扳茄竟炎析奔淑防映辣留救遮典酿厦都五缔府路署赌钾谢汇编语言讲稿10汇编语言课件10.11 批量数据的传递n编程:将data段中的字符串转化为大写。assume cs:code data segment db conversation data ends code segment start:code ends end start琵攘犀奖歧但缠脆疵咨范赘坛挂赫挥苑柬皖妮葵程傲锋臀胡锹尘桌韶禹寓汇编语言讲稿10汇编语言课件10.11 批量数据的传递n编程:将data段中的字符串转化为大写。n源程序代码n注意:除了寄存器传递参数外,还有一种通用的方法使用栈来传递参数。关于这种技巧请参看附注4。袱算脚怂扮厉画烦滇径趋旦鲍笋懒赂盏帕熏穗斯阁阑吨刊毡索旨幼实孙编汇编语言讲稿10汇编语言课件10.12 寄存器冲突的问题n设计一个子程序:n功能:将一个全是字母,以0结尾的字符串,转化为大写。n程序要处理的字符串以0作为结尾符,这个字符串可以如下定义:n db conversation,0校杆哎扭自菱夸孺储郭袄让障石妻受侮温捅宾梭怯穿稼灸且疾轿鲤囊颗驴汇编语言讲稿10汇编语言课件10.12 寄存器冲突的问题n设计一个子程序:n功能:将一个全是字母,以0结尾的字符串,转化为大写。n分析 应用这个子程序,字符串的内容后面定要有一个0,标记字符串的结束。子程序可以依次读取每个字符进行检测,如果不是0,就进行大写的转化,如果是0,就结束处理。由于可通过检测0而知道是否己经处理完整个字符串,所以子程序可以不需要字符串的长度作为参数。我们可以用jcxz来检测0。集拽丘荆自啪坦髓宅鹿阑脾焊鹿峦仇赣乒哗仔削珐哭擒增鹤娟唬躯欣开埔汇编语言讲稿10汇编语言课件10.12 寄存器冲突的问题n子程序设计:n说明:将一个全是字母,以0结尾的字符串,转化为大写。n参数:ds:si指向字符串的首地址;n结果:没有返回值。n子程序代码n我们来看一下这个子程序的应用仑疙冉越衣驳兑耗拔详剂照叠衅拂妥抱叭的慈弃掣惑锻掣瞧爱太奢售靡殆汇编语言讲稿10汇编语言课件10.12 寄存器冲突的问题n程序的应用n(1)将data段中字符串转化为大写 assume cs:code data segment db conversation,0 data endsn代码段中相关程序段如下:mov ax,data mov ds,ax mov si,0 call capital敛莫餐崎郡耘槛座鳖唇涕羞排沂嚼讣鞍告诣增尧媳旱铡绘欠溶多撅七乾隶汇编语言讲稿10汇编语言课件10.12 寄存器冲突的问题n子程序的应用n(2)将data段中字符串全部转化为大写 assume cs:code data segment db word,0 db unix,0 db wind,0 db good,0 data endsn可以看到,所有字符串的长度都是5(算上结尾符 0),我们使用循环,重复调用子程序capital完成对4个字符串的处理。n完整的程序代码凿春昏密签浊驶秆臆驱柏捂劳甜瑟吠管锰厩玲拓刁洋皋宪椒农司帜杨鞭姿汇编语言讲稿10汇编语言课件10.12 寄存器冲突的问题n问题10.2 前面的程序在思想上完全正确,但在细节上却有些错误,把错误找出来。思考后看分析。眼慨谭祷缘菱踪览硫蒂望伺仔劲阜煎清捷鸯互蔷计吠随恋瑰逐简政恫椰册汇编语言讲稿10汇编语言课件10.12 寄存器冲突的问题n问题10.2分析 问题在于cx的使用,主程序要使用cx记录循环次数,可是子程序中也使用了cx,在执行子程序的时候,cx中保存的循环计数值被改变,使得主程序的循环出错。从上而的问题中,实际上引出了个一般化的问题:子程序中使用的寄存器,很可能在主程序中也要使用,造成了寄存器使用上的冲突。砸罚湘妒孵呵馏釉害并矽援詹谬欺骚冗志顺谣卖厕押萤媒讫屈厅去迟贡诱汇编语言讲稿10汇编语言课件10.12 寄存器冲突的问题n问题10.2分析(续)那么我们如何来避免这种冲突呢?粗略地看,我们可以有两个方案:n(1)在编写调用子程序的程序时,注意看看子程序中有没有用到会产生冲突的寄存器,如果有,调用者使用别的寄存器;n(2)在编写子程序的时候,不要使用会产生冲突的寄存器。蕴罪驹浆抬胶羊铸尼汪跑盐这仓屈矢瘦贴让钥碴塘芽枢目茁苯院刃粥描喷汇编语言讲稿10汇编语言课件10.12 寄存器冲突的问题n问题10.2分析(续)我们来分析一下上面两个方案的可行性:n(1)这将给调用子程序的程序的编写造成很大的麻烦,因为必须要小心检杳所调用的子程序中是否有将产生冲突的寄存器。比如说,在上面的例子中,我们在编写主程序的循环的时候就得检查子程序巾是否用到了bx和cx,因为如果子程序中用到了这两个寄存器就会出现问题。如果我们采用这种方案来解决冲突的话,那么在主程序的循环中,就小能使用cx寄存器,因为子程序中己经用到。冒孰中凹纹戳奔入狡墅间硝匈计散吗秉仓隶房借耶肥砸准专最圭胯桌港社汇编语言讲稿10汇编语言课件10.12 寄存器冲突的问题n问题10.2分析(续)分析一下上面两个方案的可行性:n(2)这个方案是不可能实现的,因为编写子程序的时候无法知道将来的调用情况。n可见,我们上面所设想的两个方案都不可行。扩瘸叮凯纹墟孕寿蹦埠谆嘎躺姜栏丫糊真掏奈镇容帽精蚜色烁为痈缅嘶桃汇编语言讲稿10汇编语言课件10.12 寄存器冲突的问题n问题10.2分析(续)我们希望:n(1)编写调用了程序的程序的时候不必关心子程序到底使用了哪些寄存器;n(2)编写了程序的时候不必关心调用者使用了哪些寄存器;n(3)不会发生寄存器冲突。展姬攻净嘎日逸堂碎坷泵爷徒粪诧翠传拂叼机咒逸横渔辟噬菇套腊进亦概汇编语言讲稿10汇编语言课件10.12 寄存器冲突的问题n问题10.2分析(续)n解决这个问题的简捷方法是,在子程序的开始将子程序中所有用到的寄存器中的内容都保存起来,在子程序返回前再恢复。我们可以用栈来保存寄存器中的内容。滚妈蚂癸檬烤拇婴朗商夺渺口柠拿郴耐懒宫环绢蛛涨炒航娜辨冈垒攫换将汇编语言讲稿10汇编语言课件10.12 寄存器冲突的问题n问题10.2分析(续)以后,我们编写子程序的标准框架如下:子程序开始:子程序中使用的寄存器入栈 子程序内容 子程序使用的寄存器出栈 返回(ret、retf)我们改进一下子程序capital的设计京希姓薪杜蠢外引沤舜亦龟厚宰问炸蔑溜圈裤么恨婶绣闻肌乾亨尧晰啥配汇编语言讲稿10汇编语言课件10.12 寄存器冲突的问题n问题10.2改进的子程序capital的设计capital:push cx push si change:mov cl,si mov ch,0 jcxz ok and byte ptr si,11011111b inc si jmp short change ok:pop si pop cx retn要注意寄存器入栈和出栈的顺序。粒氧氦就札剔雷得背忻殆媚氰仲皇彻视纲宾骆梆弛蕾夯移允辣刃磐枷查匪汇编语言讲稿10汇编语言课件嚣掏明滔酷惺强煞炮虎繁汰绊谚批虾建俘没亦诊挣蚂腐枉垛泻慧棺逻产质汇编语言讲稿10汇编语言课件小结针遮指柞捉宫通柜伐喜抄贾梁挣恃慕拦瓤碘色寇毗沾涂绒搅腔弘媚夺吉惶汇编语言讲稿10汇编语言课件
展开阅读全文