《6.1 子例程机制电子课件 计算机系统基础:C语言视角(RISC-V版).ppt》由会员分享,可在线阅读,更多相关《6.1 子例程机制电子课件 计算机系统基础:C语言视角(RISC-V版).ppt(22页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、6.1 子例程机制电子课件 计算机系统基础:C语言视角(RISC-V版)子例程子例程子程序子程序现代程序设计语言的灵魂现代程序设计语言的灵魂提供了提供了抽象抽象的能力的能力将一个组件的功能与其实现的细节分隔开来将一个组件的功能与其实现的细节分隔开来程序员只需理解组件的结构,不需要考虑其实现程序员只需理解组件的结构,不需要考虑其实现的细节,就能够把该组件作为一个程序块使用的细节,就能够把该组件作为一个程序块使用子程序使程序员能够以子程序使程序员能够以模块化模块化的方式写程序,提的方式写程序,提高了构建复杂系统的能力高了构建复杂系统的能力子例程子例程在一个程序中在一个程序中,多次执行某个程序片段多
2、次执行某个程序片段在程序内在程序内,不必每次不必每次给出这个程序片段给出这个程序片段通过通过多次调用多次调用该程序片段实现该程序片段实现子例程子例程(SubroutineSubroutine)/函数函数(FunctionFunction,C C语语言)言)子例程机制子例程机制调用调用/返回机制返回机制程序片段程序片段A A示例示例程序片段程序片段A A:做乘法运算的指令序列:做乘法运算的指令序列x9=x10*x11x9=x10*x11 andix9,x9,0#x9,积,积loop:.#省略省略x9=x10*x11的实现细节的实现细节jloopexit:.#下一个任务下一个任务调用调用/返回机制
3、返回机制调用机制调用机制计算子例程的起始地址,加载到计算子例程的起始地址,加载到PCPC,并并保存返回保存返回地址地址返回机制返回机制将返回地址加载到将返回地址加载到PCPC中中JALJAL和和JALRJALR指令指令使用无条件跳转指令,实现了调用使用无条件跳转指令,实现了调用/返回机制返回机制JALJAL:Jump and LinkJump and Link“PC-PC-相对相对”寻址模式,计算子例程的起始地址寻址模式,计算子例程的起始地址JALRJALR:Jump and Link RegisterJump and Link Register“基址基址+偏移量偏移量”寻址模式,计算子例程的
4、起始地址寻址模式,计算子例程的起始地址通常设置目标寄存器为通常设置目标寄存器为x1x1,保存返回地址,保存返回地址/链链接接JALJALPC PC PC+SEXT(imm20:0)PC+SEXT(imm20:0)x1x1 PC+4 PC+4地址地址31 1211 76 0 x0040 00000 0000000110 0 00000000000011101111imm20|10:1|11|19:12x1jalJALJAL指令指令汇编汇编格式格式JALJAL x1,x1,LABELLABELLABELLABEL,标识,标识JALJAL指令的指令的目标目标例如,例如,jal x1,jal x1,M
5、ultiplyMultiply下一条被执行的指令下一条被执行的指令被被MultiplyMultiply标识的指令标识的指令并且并且,在在x1x1中保存返回地址中保存返回地址MultiplyMultiply子例程子例程Multiply:andix9,x9,0#x9,积,积loop:.#省略省略x9=x10*x11的实现细节的实现细节jloopexit:jalr x0,0(x1)#返回返回使用使用jalr x0,0(x1)jalr x0,0(x1)结束子例程结束子例程JALRJALRPC PC (rs1)+SEXT(imm11:0)(rs1)+SEXT(imm11:0)x1 x1 PC+4 PC+
6、4jalrjalr指令的汇编指令格式为指令的汇编指令格式为jalrjalrx1,imm12(rs1)x1,imm12(rs1)或或 jalrjalrx1,rs1,imm12x1,rs1,imm12地址地址31 2019 1514 1211 76 0 x0040 00001111 1111 110000101000000011100111imm11:0 x5jalrx1I-类型跳转问题:什么是问题:什么是JALRJALR指令能够提供的而指令能够提供的而JALJAL指令指令无法提供的重要特点?无法提供的重要特点?jaljal指令指令计算出的地址被限制于内存的一定范围之内计算出的地址被限制于内存的一
7、定范围之内偏移范围为偏移范围为-2-22020到到2 22020-1-1jalrjalr指令指令对于下一条被执行的指令位于何处没有限制对于下一条被执行的指令位于何处没有限制伪指令伪指令callcall使用使用JALRJALR指令,调用子例程:指令,调用子例程:如何计算子例程的起始地址,将其赋值给如何计算子例程的起始地址,将其赋值给rs1rs1?对于汇编程序员来说,可以使用伪指令,简化编对于汇编程序员来说,可以使用伪指令,简化编程工作程工作call Labelcall Label汇编器将其翻译为汇编器将其翻译为jalrjalr指令指令call Labelcall Label汇编器按照内存分配的规
8、则汇编器按照内存分配的规则1 1、计算出标记相对于、计算出标记相对于PCPC的偏移量的偏移量offsetoffset(3232位)位)2 2、将、将3232位的位的offsetoffset拆分成高拆分成高2020位和低位和低1212位位3 3、将伪指令、将伪指令callcall翻译为:翻译为:auipcauipcrd,rd,offsetHioffsetHi#offsetHi#offsetHi是是offsetoffset的高的高2020位位jalrjalrx1,x1,offsetLooffsetLo(rd)(rd)#offsetLo#offsetLo是是offsetoffset的低的低1212位
9、位子例程相关的伪指令子例程相关的伪指令伪指令伪指令基本指令基本指令含义含义call Label auipc rd,offsetHijalrx1,offsetLo(rd)调用子例程调用子例程retjalr x0,0(x1)从从 子子 例例 程程 返返 回回(Return,ret)示例:乘法运算示例:乘法运算计算两个二进制补码整数的乘法,采用与十进计算两个二进制补码整数的乘法,采用与十进制乘法相同的算法制乘法相同的算法以以3 3(-2)(-2)为例,采用为例,采用4 4位二进制补码表示位二进制补码表示 0 0 1 1(3)1 1 1 0(-2)0 0 0 0(0)0 1 1 (0 0)1 1 +(
10、0 0 1)1 1 0 1 0(-6)从右向左依次从右向左依次计计算,算,将被乘数与将被乘数与0或或1相相乘,乘,结结果是果是0或保或保持不持不变变MultiplyMultiply子例程子例程0202行:如果乘数为行:如果乘数为0 0,计算任务结束,计算任务结束0303行和行和0404行:判断乘数最右边一位是否为行:判断乘数最右边一位是否为1 1如果是如果是1 1,0505行指令将被乘数加到积上行指令将被乘数加到积上0606行:乘数逻辑右移行:乘数逻辑右移1 1位位0707行:被乘数左移行:被乘数左移1 1位位01Multiply:andix9,x9,0#x9,积,积02Mloop:beqzx
11、11,Mexit#x11,乘数,乘数03andix8,x11,104beqzx8,Mnext05addx9,x9,x10#x10,被乘数,被乘数06Mnext:srlix11,x11,107sllix10,x10,108jMloop09Mexit:ret#jalr x0,0(x1)问题:问题:调用调用MultiplyMultiply子例程的程序子例程的程序,如果使用寄存器如果使用寄存器x8x8存储了一个数值存储了一个数值x x在执行在执行call call MultiplyMultiply指令返回后,再次使用指令返回后,再次使用x8x8做运算,会发生什么情况?做运算,会发生什么情况?x8x8:
12、在子例程中已被改为在子例程中已被改为0 0或或1 101addix10,x0,3#x10 3,被乘数,被乘数02addix11,x0,-2#x11 -2,乘数,乘数03call Multiply04.#使用使用x8做计算做计算05.#下一个任务下一个任务callee-savecallee-save(被调用者保存)(被调用者保存)在子例程中完成寄存器的保存在子例程中完成寄存器的保存/恢复工作恢复工作0303行:使用数据区的行:使用数据区的4 4个存储单元作为保存寄个存储单元作为保存寄存器的空间存器的空间01 .data02 .align203 SaveReg1:.word0#保存寄存器的空间保存
13、寄存器的空间04#05.text06.align207#省略代码,省略代码,x8 x08addix10,x0,3#x10 3,被乘数,被乘数09addix11,x0,-2#x11 -2,乘数,乘数0Acall Multiply0B.#使用使用x8做计算做计算0C.#下一个任务下一个任务0E0E和和0F0F行:将行:将x8x8的值的值x x保存到预留的空间中保存到预留的空间中1818行:将行:将x8x8的值恢复的值恢复0D#0E Multiply:lax5,SaveReg10Fswx8,0(x5)#callee-save10andix9,x9,0#x9,积,积11 Mloop:beqzx11,M
14、exit#x11,乘数,乘数12andix8,x11,113beqzx8,Mnext14addx9,x9,x10#x10,被乘数,被乘数15 Mnext:srlix11,x11,116sllix10,x10,117jMloop18 Mexit:lwx8,0(x5)#寄存器恢复寄存器恢复19ret参数和返回值参数和返回值MultiplyMultiply子例程子例程x10 x10和和x11x11是参数,是参数,x9x9是返回值是返回值调用调用MultiplyMultiply子例程的程序子例程的程序先传递参数值,即为先传递参数值,即为x10 x10和和x11x11赋值赋值调用返回后,通过返回值调用返回后,通过返回值x9x9得到乘法计算结果得到乘法计算结果