《北大计算机构造与组成课件MIPS》由会员分享,可在线阅读,更多相关《北大计算机构造与组成课件MIPS(23页珍藏版)》请在金锄头文库上搜索。
1、MIPS 代码生成,MIPS 代码是一种汇编代码 主要汇编信息: .text /代码段(指令段) .data /数据段 .globl /全局符号声明 .align 0 /关闭所有的自动对齐 .asciiz /字符串(带终止符),MIPS的寄存器约定,a0 - a3:存放向子函数传递的参数 v0、v1:存放子函数调用返回结果 还可用于表达式求值 s0 - s7:存放局部变量 在发生函数调用时一般要保存它们的内容 t0 t8:存放临时运算结果 在发生函数调用时不必保存它们的内容 sp: 栈(stack)指针 fp: 帧(frame)指针 ra: 返回地址(用于过程调用),MIPS指令,运算 add
2、u, add subu, sub mul and neg 常数操作 li,数据传输 la lw sw move 比较 seq slt,MIPS指令,控制指令 b label: 分支到 label beqz Rsrc, label:如果 Rsrc 为 0 就分支到 label bgeu Rsrc1, Src2, label:如果 Rsrc1 大于等于 Src2 就分支到 label j label: 无条件转移到 label jal label:(jump and link) 无条件转移到 label, 并将下一指令的地址写入 $ra jalr Rsrc: 使用寄存器的跳转指令 指令的跳转地址在
3、 Rsrc 寄存器中 并将下一指令的地址写入 $ra,更多细节见:http:/www.cs.purdue.edu/homes/hosking/352/spim/raw.html 体系结构课程的相关资料,系统调用指令:syscall $v0 中包含调用号(共12个): 1:打印整数,数字在 $a0 中 4:打印字符串,字符串在 $a0 中 9:申请内存块,申请长度在 $a0 中, 所获得内存的地址在$v0中,MIPS指令,堆栈操作,对每个子例程堆栈空间排列可以参考:* 高地址 -低地址 * -*| ra | fp |溢出TEMP |保存用到的S寄存器|参数X|.| 参数4 | 下一帧* - fp
4、指向上个sp,0($fp)可以取到入参数4,依次类推。 参数的个数是当前子例程调用其他例程时需传参数的最大数减去4. 子例程开始时:1. 操作堆栈,分配空间。2. 保存所有用到的S寄存器。3. 将所有用到的入参拷贝到S寄存器或T寄存器或溢出空间里。结束时:恢复S寄存器和堆栈。,对出现在子例程中的所有TEMP: 如果它从来不活跃,例如(只写未读或未写未读),该TEMP只可能是MOVE或HLOAD目标,可以转化该语句为nop。 如果它的活性区间跨调用(出现在至少一个CALL语句的LiveOut中),分配s寄存器,或溢出。 如果它的活性区间不跨调用,优先分配t寄存器,其次s寄存器,或溢出。 可以用v
5、0和v1存取溢出的TEMP。,MAIN 002 MOVE t0 HALLOCATE 4 MOVE t1 HALLOCATE 4 MOVE t2 Fac_ComputeFac HSTORE t0 0 t2 HSTORE t1 0 t0 MOVE t0 t1 HLOAD t1 t0 0 HLOAD t2 t1 0 MOVE t1 10 MOVE a0 t0 MOVE a1 t1 CALL t2 MOVE t3 v0 PRINT t3 END,.text /指令段 .globl main main: /主函数 move $fp, $sp /记录上帧首址 subu $sp, $sp, 4 /设置本帧栈
6、长 sw $ra, -4($fp) /保存返回地址 li $a0 4 /将数值4设为入参 jal _halloc /调用子过程获取内存 move $t0 $v0 /保存所获内存首址 li $a0 4 /将数值4设为入参 jal _halloc /调用子过程获取内存 move $t1 $v0 /保存所获内存首址 la $t2 Fac_ComputeFac/获取子过程地址 sw $t2, 0($t0) /将直接地址存起来 sw $t0, 0($t1) /将间接过程存起来 move $t0 $t1 /获取间接过程地址 lw $t1 0($t0) /获取间接过程 lw $t2 0($t1) /获取直接
7、地址 li $t1 10 /加载整数10 move $a0 $t0 /将间接地址设为入参 move $a1 $t1 /将10设为入参 jalr $t2 /调用子过程 move $t3 $v0 move $a0 $t3 jal _print /打印结果 lw $ra, -4($fp) /获取返回值地址 addu $sp, $sp, 4 /弹出栈内容 j $ra / 返回,Fac_ComputeFac 232 ASTORE SPILLEDARG 0 s0 ASTORE SPILLEDARG 1 s1 ASTORE SPILLEDARG 2 s2 MOVE s0 a0 MOVE s1 a1 MOVE
8、 t0 1 MOVE t1 LT s1 t0 CJUMP t1 L2 MOVE s2 1 JUMP L3 L2 NOOP MOVE t0 s0 HLOAD t1 t0 0 HLOAD t2 t1 0 MOVE t1 1 MOVE t3 MINUS s1 t1 MOVE a0 t0 MOVE a1 t3 CALL t2 MOVE t1 v0 MOVE t0 TIMES s1 t1 MOVE s2 t0 L3 NOOP MOVE v0 s2 ALOAD s0 SPILLEDARG 0 ALOAD s1 SPILLEDARG 1 ALOAD s2 SPILLEDARG 2 END,.text Fac
9、_ComputeFac: sw $fp, -8($sp) /保存上上帧首址 move $fp, $sp /设置上帧首址 subu $sp, $sp, 20/设置本帧栈长 sw $ra, -4($fp) /保存返回地址 sw $s0, 0($sp) /保存老入参1 sw $s1, 4($sp) /保存老入参2 sw $s2, 8($sp) /保存返回值 move $s0 $a0 /取新入参1 move $s1 $a1 /取新阶乘因子 li $t0 1 / 加载数值1 slt $t1, $s1, $t0 /比较阶乘因子与1 beqz $t1 L2 /如果大于1转L2 li $s2 1 /加载1给计
10、算结果 b L3 /跳转 L3 L2: nop move $t0 $s0 /取入参(间接地址) lw $t1 0($t0) /加载间接地址 lw $t2 0($t1) /加载直接地址 li $t1 1 /加载数值1 sub $t3, $s1, $t1 /阶乘因子减1 move $a0 $t0 /将间接地址设为入参 move $a1 $t3 /将阶乘因子设为入参 jalr $t2 /递归调用 move $t1 $v0 /获取返回的计算结果 mul $t0, $s1, $t1 /阶乘因子乘结果 move $s2 $t0 /得到新结果 L3: nop move $v0 $s2 /准备返回新结果 lw
11、 $s0, 0($sp) /恢复局部变量内容 lw $s1, 4($sp) /恢复局部变量内容 lw $s2, 8($sp) /恢复局部变量内容 lw $ra, -4($fp) /获取返回地址 lw $fp, 12($sp) /获取上帧首址 addu $sp, $sp, 20 /弹出栈 j $ra /返回,.text .globl _halloc _halloc: li $v0, 9 syscall j $ra .text .globl _print _print: li $v0, 1 syscall la $a0, newl li $v0, 4 syscall j $ra .data .al
12、ign 0 newl: .asciiz n .data .align 0 str_er: .asciiz ERROR: abnormal terminationn,内存分配基本约定 指令段:0 x00400000 数据段:0 x10000000 运行栈:0 x7fffffff,帧与栈的运行效果?请见下页,move $fp, $sp subu $sp, $sp,4 sw $ra, -4($fp) . jalr $t2 Fac_ComputeFac: sw $fp, -8($sp) move $fp, $sp subu $sp,$sp,20 sw $ra, -4($fp) sw $s0, 0($s
13、p) sw $s1, 4($sp) sw $s2, 8($sp) jalr $t2 move $t1 $v0 mul $t0,$s1,$t1 move $s2 $t0 move $v0, $s2 lw $s0,0($sp) lw $s1,4($sp) lw $s2,8($sp) lw $ra,-4($fp) lw $fp,12($sp) addu $sp,$sp,20 j $ra,sp,fp,0 x7ffffef78,f74,f70,f6c,f68,f64,f60,f5c,f58,f54,f50,f4c,f48,f44,f40,f3c,0 x00400018,0 x00400074,返回地址,
14、返回地址,返回地址,上上帧首址,上上帧首址,0 x7fffef78,0 x00000000,0 x00000000,0 x00000000,0 x004000fc,0 x7fffef74,0 x10040004,0 x0000000a,0 x00000000,0 x004000fc,0 x7fffef60,0 x10040004,0 x00000009,0 x00000000,0 x7ffffef78,0 x7ffffef78,0 x7ffffef74,0 x7ffffef74,0 x7ffffef60,0 x00400018,ra,0 x00400024,0 x00400028,0 x00400070,0 x00400074,0 x004000f8,0 x00400074,0 x004000fc,0 x004000fc,0 x7ffffef60,0 x7ffffef4c,间接地址,阶乘因子,0 x004000a0,0 x10040004,0 x10040000,0 x10040000,0 x000400a0,返回地址,上上帧首址,间接地址,阶乘因子,0 x7ffffef4c,0 x7ffffef38,f38,数据段,