Directives声明变量值存储

容易将数据段地址和地址上的内容搞混

.data
fibs: .space 48 # allocate 12 * 4 = 48 Byte memory, store first address in label "fibs"
size: .word 12 # allocate 1 Byte(a word) for 12, store address in label "size" .text # want to load the value of "size" (12) to $t5
la $t5, size # 1. load the address of "size" to $t5, for we could only use the label
lw $t5, 0($t5) # 2. load the value of "size" to $t5

需厘清:寄存器编号(地址);寄存器值;内存地址;内存段值

程序操纵寄存器,寄存器操纵内存地址

表示地址:1.立即数(+标签) 2.寄存器取值

二维数组使用

标准

Arr: .space 800

.macro getindex(%ans, %i, %j, %rank)  # for Arr[][rank]
mult %i, %rank
mflo %ans
add %ans, %ans, %j
sll %ans, %ans, 2
.end_macro .text
li $t0, 4
li $t1, 0
li $t2, 8
getindex($t3, $t0, $t1, $t2)
lw $s0, Arr($t3) # load Arr[4][0] to $s0
sw $s0, Arr($t3) # store $s0 to Arr[4][0]

一些存储带来的简化

.data
Arr: .space 800 # Arr[25][8]: 25 * 8 * 4Byte
# cols最好用2的幂,方便sll操作,不用mult
.macro getindex_8(%ans, %i, %j) # calculate (i*8+j)*4
sll %ans, %i, 3 # i << 3
add %ans, %ans, %j
sll %ansm %ans, 2
.end_macro
# never manipulate the value of %i, %j , which prevent the risk of mischanging other registers when using the macro
# thus "getindex($t0, $t1, $t1)" is safe to both the result and $t1
# 模块化维护某些规范,便无需在其他地方多虑。寄存器使用惯例、函数栈的意义在此。

这里将标签的首地址立即数直接作为offset,将感觉上的偏移作为base,效果不错。

不过是不是还得小心位数,address:32bit 而 offset:16bit ?是只传了低 16bit 吗

循环

for循环 for(int i=0;i<n;++i)

li $t0, 0                    # int i=0 ($s0 store the value of n)
for_i_begin:
slt $t1, $t0, $s0 # i < n ? 1 : 0 can be changed to other comparing instruction
beqz $t1, for_i_end # ATTENTION: please match the comparing instruction , easy to mix up # other instruction addi $t0, $t0, 1 # ++i
j for_i_begin # continue loop
for_i_end:

函数调用

约定,类似$t0$t1等寄存器记作$t

所谓$t由父函数维护,$s由子函数维护。

$s为正当的“存储寄存器”,因而当前父函数中不应操心,由其内部子函数维护该寄存器存储的效果;$t为正当的“临时寄存器”,本不应该存储数据,因而子函数不应操心可以随便用,若想要存储则应由当前父函数自己操心)

  • 预处理

    1. .data栈空间申请
    2. $sp指向栈顶
  • 父函数调用子函数
    1. 若有需要维护的变量,应事先在函数头处分为该父函数分配栈帧
    2. 传出参数: 在$a0$a1等寄存器(称为$a,后同)处加载需传出的数据
    3. 维护变量-前: 考虑该父函数中需要保留的$t$ra等寄存器,逐条载入栈帧中
    4. 调用函数jal function
    5. 维护变量-后: 将之前于栈帧中存好的数据逐条载回$ra$t等寄存器
    6. 接收返回值: 从$v中取回传回的数据
  • 子函数被调用
    1. 根据函数所需,为该子函数分配栈帧
    2. 维护变量-前: 考虑需要用到的$s寄存器,逐条载入栈帧中
    3. 取出传入参数: 将$a中传入的参数存到自己需要的地方
    4. 子函数内容
    5. 传回返回值: 将返回值载入$v
    6. 维护变量-后: 将之前于栈帧中存好的数据逐条载回$t寄存器

示例:调用int son_function(int i,int j){}

.data
stack: .space 300 .text
la $sp, stack
addiu $sp, $sp, 300 # ...... father_function:
addiu $sp, $sp, -12 # using registers for operation
# registers $s0, $s1 are used to store partial variables
# registers $t0, $t1 are still not used up move $a0, $t2
move $a1, $t3 sw $t1, 8($sp)
sw $t0, 4($sp)
sw $ra, 0($sp) # not necessary, depending on son_function
jal son_funtion
lw $ra, 0($sp)
lw $t0, 4($sp)
lw $t1, 8($sp) addiu $sp, $sp, 12
jr $ra # in son_function,
son_function:
addiu $sp, $sp, -8
sw $s1, 4
sw $s0, 0
move $t0, $a0
move $t1, $a1 # using registers for operation
# finally get return_value in $s1
# suppose no other function calling -- leaf function.
# (needn't have saved $ra in father function, just lazy to delete) move $v0, $s1
lw $s0, 0
lw $s1, 4
addiu $sp, $sp, 8
jr $ra

跳转条件判断

比较跳转指令

bgt $t0, $t1, label/bgt $t0, 100, label均可,第二个可为reg、16位imm、32位imm

指令 跳转条件 拆分
bgt > slt+bne
bge >= slt+beq
blt <
ble <=
beq == /
bne != /

指令后加z便是将$t1变为0

跳转条件书写

if(exp)

1.顺逻辑

slt sle sgt sge 判断exp真值;beqz bnez 根据真值是否为零决定跳转。

跳转伪指令(pseudo instruction)多半会按这种形式拆分成基础指令,标准的逻辑思路。注意sle sge一般会转化为slt+ori+subu之类的,指令效率低,建议换

2.反逻辑

直接使用bgt bge blt ble 判断!exp真值,真了就跳转。

清爽很多,虽然指令效率和上面一样。同样少用bgeble,通过反向来消除等号

复合条件

就是短路逻辑,感觉复杂了也挺繁琐的。

增添set_1: set_0:标签来完成短路跳转好像还不错。

具体规律遇到再说。

常见Pseudo Instruction分解

【MIPS】经典指令块集锦的更多相关文章

  1. July-程序员面试、算法研究、编程艺术、红黑树、数据挖掘5大经典原创系列集锦与总结

    程序员面试.算法研究.编程艺术.红黑树.数据挖掘5大经典原创系列集锦与总结 http://blog.csdn.net/v_july_v/article/details/6543438

  2. 计算机系统6-> 计组与体系结构3 | MIPS指令集(中)| MIPS汇编指令与机器表示

    上一篇计算机系统5-> 计组与体系结构2 | MIPS指令集(上)| 指令系统从顶层讲解了一个指令集 / 指令系统应当具备哪些特征和工作原理.这一篇就聚焦MIPS指令集(MIPS32),看看其汇 ...

  3. Nginx 的 Location 配置指令块

    最近一段时间在学习 Nginx ,以前一直对 Nginx 的 Location 配置很头大,最近终于弄出点眉目.总结如下:nginx 配置文件,自下到上分为三种层次分明的结构: |    http b ...

  4. 面试经典算法题集锦——《剑指 offer》小结

    从今年 3 月份开始准备找实习,到现在校招结束,申请的工作均为机器学习/数据挖掘算法相关职位,也拿到了几个 sp offer.经历这半年的洗礼,自己的综合能力和素质都得到了一个质的提升. 实话说对于未 ...

  5. 关于MVC4中EFCoderFirst 数据迁移的三句经典指令

    首先输入这句指令     enable-migrations -contexttypename SchoolContext  ---------(SchoolContext为你设置的数据库名)它会自动 ...

  6. [札记]IL经典指令解析之方法调度

    call.callvirt和calli指令用于完成方法调用,有何区别呢? 1)call使用静态调度,也就是根据引用类型的静态类型来调度方法.call指令根据引用变量的类型来调用方法,因此通常用于调用非 ...

  7. MIPS 汇编指令学习

    MIPS 寄存器 MIPS comes with 32 general purpose registers named $0. . . $31Registers also have symbolic ...

  8. Angular.js实现折叠按钮的经典指令.

    var expanderModule=angular.module('expanderModule',[]) expanderModule.directive('expander',function( ...

  9. SqlServer教程:经典SQL语句集锦

    SQL分类: DDL—数据定义语言(CREATE,ALTER,DROP,DECLARE) DML—数据操纵语言(SELECT,DELETE,UPDATE,INSERT) DCL—数据控制语言(GRAN ...

  10. 经典SQL语句集锦

      下列语句部分是MsSql语句,不可以在access中使用. SQL分类: DDL—数据定义语言(CREATE,ALTER,DROP,DECLARE) DML—数据操纵语言(SELECT,DELET ...

随机推荐

  1. Debian 11 (bullseye) 国内软件源

      本文整理了Debian 11在国内的几个软件源. 1.使用说明 一般情况下,将/etc/apt/sources.list文件中Debian默认的软件仓库地址和安全更新仓库地址修改为国内的镜像地址即 ...

  2. .NET周刊【12月第3期 2024-12-15】

    国内文章 重磅推出 Sdcb Chats:一个全新的开源大语言模型前端 https://www.cnblogs.com/sdcb/p/18597030/sdcb-chats-intro Sdcb Ch ...

  3. Qt编写物联网管理平台37-逻辑设计

    一.前言 本系统的逻辑设计是个人认为做过的系统中最好的,一个系统支持多个通信端口,每个通信端口都可选不同的通信协议,一个通信端口可以接255个控制器,相当于主设备,一个控制器可以接255个探测器,相当 ...

  4. [转]OpenCV4.8 GPU版本CMake编译详细步骤 与CUDA代码演示

    导 读 本文将详细介绍如何使用CMake编译OpenCV4.8 CUDA版本并给出Demo演示,方便大家学习使用. CMake编译详细步骤 废话不多说,直接进入正题! [1]我使用的工具版本VS201 ...

  5. [转]点云库PCL从入门到精通 随书源码(百度网盘下载)

    分享给需要的人. 这里有你想要的东西-暗号-pdx6 相关链接: PCL点云数据处理基础️️️目录

  6. 跟着源码学IM(十一):一套基于Netty的分布式高可用IM详细设计与实现(有源码)

    本文由will分享,个人博客zhangyaoo.github.io,原题"基于Netty的IM系统设计与实现",有修订和重新排版. 1.引言 本文将要分享的是如何从零实现一套基于N ...

  7. Verilog3_组合逻辑电路

    组合逻辑电路设计方法 使用assign语句: 描述简单的组合逻辑电路 使用always块: 描述复杂的组合逻辑电路 要点: 只在一个always模块中对某一变量进行赋值: 将所有敏感变量列在敏感变量列 ...

  8. 从单体架构、到SOA、再到微服务的架构设计详解

    本文涉及的内容以及知识点如下: 1.单体架构 2.单体架构的拆分 3.SOA与微服务的区别 4.微服务的优缺点 5.微服务的消息 6.服务集成 7.数据的去中心化 单体架构 Web应用程序发展的早期, ...

  9. C# 单例简单实例

    1 using System; 2 using System.Collections.Generic; 3 using System.ComponentModel; 4 using System.Li ...

  10. C#定点执行任务测试案例

    定时方法实现类 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text ...