关于MIPS上手应知应会-如何把C语言改写为MIPS!

文章目录

  • 寄存器
  • 指令
  • 使用技巧
    • 翻译C/C++
      • if/else语句
      • switch语句
      • for循环
      • while 循环
      • do...while循环
      • 一维数组定义与使用
      • 二维数组定义与使用
      • 例 :哈密顿回路
  • 注意
    • 立即数被符号位扩展
  • 参考链接

寄存器

NameReg. NumUsage
z e r o zero zero0constant value =0(恒为0)
a t at at1reserved for assembler(为汇编程序保留)
v 0 – v 1 v0 – v1 v0–v12 – 3values for results(过程调用返回值)
a 0 – a 3 a0 – a3 a0–a34 – 7Arguments(过程调用参数)
t 0 – t 7 t0 – t7 t0–t78 – 15Temporaries(临时变量)
s 0 – s 7 s0 – s7 s0–s716 – 23Saved(保存)
t 8 – t 9 t8 – t9 t8–t924 – 25more temporaries(其他临时变量)
k 0 – k 1 k0 – k1 k0–k126 – 27reserved for kernel(为OS保留)
g p gp gp28global pointer(全局指针)
s p sp sp29stack pointer (栈指针)
f p fp fp30frame pointer (帧指针)
r a ra ra31return address (过程调用返回地址)

指令

第一页

第二页

使用技巧

翻译C/C++

if/else语句

if(a >= b) //Do something...
else if(a < c+b) //Do something...
else //Do something...
# $s0 = a, $s1 = b, $s2 = c
if_begin:
bgt $s1, $s0, if_else1# Do something
if_else1:
add $t0, $s1, $s2
bngt $t0, $s0, if_else2# Do something
if_else2:# Do something
if_end:

switch语句

switch(a) {case 2:// Do somethingbreak;case 4:// Do somethingbreak;default:// Do something
}
# $s0 = a
switch_begin:case_2:bne $s0, 2, case_4# Do somethingj switch_endcase_4:bne $s0, 4, default# Do somethingj switch_enddefault:# Do something
switch_end:

for循环

for(int i = 0; i < n; i++) // Do something
# $s0 = n
li $t0, 0
for_begin:
bne $t0, $s0, end_for # Do something
addi $t0, $t0, 1
j for_begin
end_for:

while 循环

int i = a;
while(i < n) {// Do something...i++;
}
# $s0 = n, $s1 = a, $t0 = i
move $t0, $s1
while_begin:
bne $t0, $s0, end_while# Do somethingaddi $t0, $t0, 1
j while_begin
end_while:

do…while循环

do {i++;//Do something
} while(i < n);
# $t0 = i, $s0 = n
li $t0, 1
dowhile:addi $t0, $t0, 1# Do something
beq $s0, $t0, end_dowhile
j dowhile
end_dowhile:

一维数组定义与使用

int arr[100];
for(int i = 0; i < 100; i++) arr[i] = i;
.dataarr: .space 400				#长度100的int型数组,总共使用400字节
.text# $t0 = ili $t0, 0;for_begin:beq $t0, 100, end_formove $t1, $t0sll $t1, $t1, 2			# i*4得到偏移的字节数,MIPS按照字节寻址,地址从x00000000, 0x00000004...以此类推# 此外MIPS还是小端地址,如果输入0x12345678,那么0x00000002存的是0x56sw $t0, arr($t1)		# 这跟直接访问还挺像的# 实际上,arr是指一系列空间的首地址,加上偏移量$t1,得到arr[i]的地址addiu $t0, $t0, 1j for_beginend_for:li $v0, 10						# 类似于C/C++中的return 0
syscall

二维数组定义与使用

#include <iostream>
using namespace std;
int arr[64][64];int main() {int m, n;cin >> n >> m;for(int i = 0; i < n; i++)for(int j = 0; j < m; j++) cin >> arr[i][j];for(int i = n-1; i >= 0; i--)for(int j = m-1; j >= 0; j--) cout << i << ' ' << j << ' ' << arr[i][j] << endl; return 0;
}
.dataarr: .space 16384# 下面两个宏定义与数组大小密切相关,64*64大小的数组是这么做的
# 我们约定$t7, $t8, $t9只在宏定义中使用
.macro setarr(%d, %i, %j)		# 把arr[i][j]设置为dsll $t8, $t8, 6add $t9, $t8, %jsll $t9, $t9, 2sw %d, arr($t9)
.end_macro
.macro getarr(%d, %i, %j)		# 把d赋值为arr[i][j]sll $t8, $t8, 6add $t9, $t8, %jsll $t9, $t9, 2lw %d, arr($t9)
.end_macro.text# $s0 = n, $s1 = mli $v0, 1syscallmove $s0, $v0li $v0, 1syscallmove $s0, $v0# $t0 = i, $t1 = jli $t0, 0li $t1, 0for_in_i:beq $t0, $s0, end_for_in_ifor_in_j:beq $t1, $s1, end_for_in_jli $v0, 1syscallsetarr($v0, $t0, $t1)addi $t1, $t1, 1j for_in_jend_for_in_j:addi $t0, $t0, 1j for_in_iend_for_in_i:# $t0 = i, $t1 = jsubi $t0, $s0, 1 subi $t1, $s1, 1for_out_i:blt $t0, 0, end_for_out_ifor_out_j:blt $t1, 0, end_for_out_jgetarr($t3, $t0, $t1)# 输出$t0, $t1, $t2这里省略了subi $t1, $t1, 1j for_out_jend_for_out_j:subi $t0, $t0, 1j for_out_iend_for_out_j:li $v0, 10						# 类似于C/C++中的return 0
syscall

例 :哈密顿回路

#include <iostream>
using namespace std;const int MAXN = 10;int G[MAXN][MAXN];
bool vis[MAXN];
int n, m;
int ans;int dfs(int i, int start) {bool flag = false;vis[i] = true;cout << i;for(int j = 1; j <= n; j++) if(!vis[j] && G[i][j]) {dfs(j, start);}for(int j = 1; j <= n; j++) if(!vis[j]) {flag = true;break;}if(G[i][start] && !flag) ans = 1;vis[i] = false;return 0;
}int main() {cin >> n >> m;for(int i = 0; i < m; i++) {int u, v;scanf("%d%d", &u, &v);G[u][v] = G[v][u] = 1;}for(int i = 1; i <= n; i++) {dfs(i, i);if(ans == 1) {cout << 1 << endl;return 0;}}cout << 0 << endl;return 0;
}
.datagraph: .space 1024vis: .space 512endl: .word '\n'.macro setGraph(%data, %i, %j)sll $t8, %i, 4add $t8, $t8, %jsll $t8, $t8, 2sw %data, graph($t8)
.end_macro
.macro getGraph(%ans, %i, %j)sll $t8, %i, 4add $t8, $t8, %jsll $t8, $t8, 2lw %ans, graph($t8)
.end_macro.text
main:# $s0 = nli $v0, 5syscallmove $s0, $v0# $s1 = mli $v0, 5syscallmove $s1, $v0move $t0, $zerofor_input:# for(i = 0; i != m; i++)beq $t0, $s1, end_for_inputli $v0, 5syscallmove $t1, $v0li $v0, 5syscallmove $t2, $v0li $t3, 1setGraph($t3, $t1, $t2)setGraph($t3, $t2, $t1)addi $t0, $t0, 1j for_inputend_for_input:li $t0, 1for_iter:# for(i = 1; i <= n; i++)bgt $t0, $s0, end_for_itermove $a0, $t0	# $a0 = pmove $a1, $t0	# $a1 = startjal dfsbeq $s3, 1, print_ansaddi $t0, $t0, 1j for_iterend_for_iter:print_ans:	li $v0, 1move $a0, $s3syscall
li $v0, 10
syscalldfs:	# $a0 = p, $a1 = start
addi $sp, $sp, -24
sw $ra, 20($sp)
sw $t0, 16($sp)
sw $t1, 12($sp)
sw $t2, 8($sp)
sw $t3, 4($sp)
sw $t4, 0($sp)sll $t0, $a0, 2li $t1, 1sw $t1, vis($t0)li $t0, 1for_nextpoint:# for(i = 1; i <= n; i++) if(graph[p][i] == 1 && !vis[i])bgt $t0, $s0, end_for_nextpointgetGraph($t1, $a0, $t0)bne $t1, 1, nextpoint_continuesll $t2, $t0, 2lw $t3, vis($t2)bne $t3, $zero, nextpoint_continuemove $t4, $a0move $a0, $t0jal dfsmove $a0, $t4nextpoint_continue:addi $t0, $t0, 1j for_nextpointend_for_nextpoint:li $t0, 1	for_check:bgt $t0, $s0, end_for_checksll $t1, $t0, 2lw $t2, vis($t1)beq $t2, $zero, end_functionaddi $t0, $t0, 1j for_checkend_for_check:getGraph($t0, $a0, $a1)bne $t0, 1, end_functionli $s3, 1end_function:sll $t0, $a0, 2sw $zero, vis($t0)
lw $ra, 20($sp)
lw $t0, 16($sp)
lw $t1, 12($sp)
lw $t2, 8($sp)
lw $t3, 4($sp)
lw $t4, 0($sp)
addi $sp, $sp, 24
jr $ra

注意

立即数被符号位扩展

  • 算术指令 :add addi sub 总是将立即数做符号位扩展即便指令是无符号的;
    乘 、 除 指令 任何情况下都不进行扩展,总是当成 unsigned
  • 逻辑指令:(andi, ori通常处理无符号数)不对立即 数做符号位扩展
  • load / store指令: 地址计算时总是扩展立即数

参考链接

  1. 谈一谈 MIPS 汇编 Challenge 题:找哈密顿回路:(https://flyinglandlord.github.io/2021/09/30/BUAA-CO-2021/Pre/%E8%B0%88%E4%B8%80%E8%B0%88MIPS%E6%B1%87%E7%BC%96Challenge%E9%A2%98/)

  2. 流水线 MIPS 处理器的设计:https://zobinhuang.github.io/sec_learning/Tech_Computer_Architerture/Architecture_6_MIPS_Pipeline/#1_intro_1

  3. 《初学计算机组成原理之MIPS指令集及汇编》: https://blog.csdn.net/weixin_51599896/article/details/123865620

  4. MIPS指令详解:https://blog.csdn.net/weixin_46308081/article/details/115798605

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/319520.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

「实战应用」如何用DHTMLX Gantt构建类似JIRA式的项目路线图(一)

DHTMLX Gantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表。可满足项目管理应用程序的所有需求&#xff0c;是最完善的甘特图图表库。 在web项目中使用DHTMLX Gantt时&#xff0c;开发人员经常需要满足与UI外观相关的各种需求。因此他们必须确定JavaScript甘特图库的…

C#编程-描述内存分配

描述内存分配 分配给变量的内存通过两种方式引用&#xff1a;值类型和引用类型。内置数据类型&#xff0c;诸如int、char和float都是值雷兴国。当您声明int变量时&#xff0c;编译器会分配一个内存块以保持该整数值。请思考以下语句&#xff1a; int Num 50;上述语句为保存值…

进阶学习——Linux系统中重点‘进程’

目录 一、程序和进程的关系 1.程序 2.进程 2.1线程 2.2协程 3.进程与线程的区别 4.总结 4.1延伸 5.进程使用内存的问题 5.1内存泄漏——Memory Leak 5.2内存溢出——Memory Overflow 5.3内存不足——OOM&#xff08;out of memory&#xff09; 5.4进程使用内存出现…

计算机视觉中的神经网络可视化工具与项目

前言 本文介绍了一些关于神经网络可视化的项目&#xff0c;主要有CNN解释器&#xff0c;特征图、卷积核、类可视化的一些代码和项目&#xff0c;结构可视化工具&#xff0c;网络结构手动画图工具。 CNN解释器 这是一个中国博士发布的名叫CNN解释器的在线交互可视化工具。 主要…

亚信安全捕获银狐木马控制端样本,揭晓最新发现

近日&#xff0c;亚信安全威胁情报中心获取到银狐远控样本&#xff0c;通过远控端生成一个Payload并对Payload进行分析&#xff0c;还原了银狐组织攻击的完整过程。建议相关用户部署全面防病毒产品&#xff0c;积极采取相关措施。 银狐木马简介 攻击者总是会将钓鱼页面部署在个…

第二证券机构策略:股指预计维持蓄势震荡格局 关注煤炭、电力等板块

第二证券以为&#xff0c;技能面看&#xff0c;在元旦节前资金抄底推进指数收回2900整数关口&#xff0c;并向着3000点渠道压力前进。沪指在底部均线位支撑摆放较强&#xff0c;调整空间估计不大&#xff0c;在3000点渠道下方调整就是再次优化低吸的时机。操作上&#xff0c;在…

[Flutter]WindowsOS上运行遇到的问题总结

[Flutter]WindowsOS上运行遇到的问题总结 写在开头 Flutter项目已能在移动端完美使用后&#xff0c;想看看在桌面端等使用情况 基于Flutter3.0后已支持Windows/MacOS等桌面端&#xff0c;不过具体的系统&#xff0c;还需要看下官方文档解释。 这里抛出文档地址&#xff0c;可…

力扣hot100 二叉树的直径

&#x1f468;‍&#x1f3eb; 题目地址 一个节点的最大直径 它左树的深度 它右树的深度 &#x1f60b; AC code /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* Tr…

XYZ世代

Z世代&#xff0c;Gen Zers&#xff0c;Generation Z &#xff0c;一词最早出现于欧美地区&#xff0c;是美国及欧洲的流行用语&#xff0c;泛指在1995-2009年间出生的一代人&#xff0c;千禧后一代。又称网络世代、互联网世代&#xff0c;网生代&#xff0c;二次元世代&#x…

基于Vue开发的一个仿京东电商购物平台系统(附源码下载)

电商购物平台项目 项目完整源码下载 基于Vue开发的一个仿京东电商购物平台系统 Build Setup # csdn下载该项目源码压缩包 解压重命名为sangpinghui_project# 进入项目目录 cd sangpinghui_project# 安装依赖 npm install# 建议不要直接使用 cnpm 安装以来&#xff0c;会有各…

thinkcmf 配置移动端模板

1.找到tinkcmf/data/config/template.php 文件 cmf_moblie_default_theme > cffff_m, 2. 找到thinkcmf/vendor/thinkcmf/src/common.php // $theme config(template.cmf_default_theme);if (cmf_is_mobile()) {$theme config(template.cmf_moblie_default_theme);} el…

仓库出入库登记系统的推荐

在信息时代&#xff0c;仓库管理已成为企业不可缺少的一项工作。我们如何高效、准确地管理仓库的进货、出货以及库存&#xff0c;是每个企业或仓管都需要面对的问题。而一个优秀的仓库出入库登记系统&#xff0c;则能够大大提升仓库管理的效率和准确性。本文将为您推荐一款实用…