← 返回首页
学习思考

mips汇编

寄存器:

指令格式:

R-Format(Register)

I-Format(Immediate)

J-Format(Jump)

内存空间:

寻址方式:

  1. 立即数寻址 - I:操作数是位于指令自身中的常数
  2. 寄存器寻址 - R:操作数是寄存器
  3. 基寻址址或偏移寻址 - I:操作数在存储器中,其地址是指令中寄存器与常数的和
  4. PC相对寻址 - I:地址是PC+4与指令中常数的和
  5. 伪直接寻址 - J:跳转地址与指令中的26位字段和PC的高位拼接而成

数据定义:

数据伪指令

如果初始值超过了值域上限汇编程序会报错

系统调用:

程序模板:

assembly
# Title: Filename: # Author: Date: # Description: # Input: # Output: ################# Data segment ##################### .data . . . ################# Code segment ##################### .text .globl main main: # main program entry . . . li $v0, 10 # Exit program syscall

实例:

下边的例子一定要看懂

1.

c
int square(int i, int j, int h, int g) { int f; f = (g + h) - (i + j); return f; }
plain text
# mips clang 16.0.0 square(int, int, int, int): # @square(int, int, int, int) addiu $sp, $sp, -32 # 分配32空间 sw $ra, 28($sp) # 将ra的值保存在sp[7]中 # 4-byte Folded Spill sw $fp, 24($sp) # 将fp的值保存在sp[6]中 # 4-byte Folded Spill move $fp, $sp # $fp = $sp,一般对变量的读取通过帧指针完成 sw $4, 20($fp) # sp[5] = i sw $5, 16($fp) # sp[4] = j sw $6, 12($fp) # sp[3] = h sw $7, 8($fp) # sp[2] = g lw $1, 8($fp) # $at = sp[2](g) lw $2, 12($fp) # $v0 = sp[3](h) addu $1, $1, $2 # $at = g + h lw $2, 20($fp) # $v0 = sp[5](i) lw $3, 16($fp) # $v1 = sp[4](j) addu $2, $2, $3 # $v0 = i + j subu $1, $1, $2 # $at = $at - $v0 sw $1, 4($fp) # sp[1] = $at lw $2, 4($fp) # $v0 = sp[1] move $sp, $fp # $sp = $fp lw $fp, 24($sp) # $fp = sp[6](old_fp) 恢复fp lw $ra, 28($sp) # $ra = sp[7](old_ra) 恢复ra,实际上代码中并没有对ra的操作,个人猜测可能是防止修改 addiu $sp, $sp, 32 # 恢复sp值 jr $ra # 返回 nop

2.

c
void strcpy(char x[], char y[]){ int i; i = 0; while((x[i] = y[i]) != '\0') i += 1; }
plain text
strcpy(char*, char*): # @strcpy(char*, char*) addiu $sp, $sp, -24 # 分配空间 sw $ra, 20($sp) # sp[5] = $ra 保存ra寄存器的值 sw $fp, 16($sp) # sp[4] = $sp 保存fp寄存器的值 move $fp, $sp # $fp = $sp sw $4, 12($fp) # sp[3] = x sw $5, 8($fp) # sp[2] = y sw $zero, 4($fp) # sp[1] = 0 j $BB0_1 nop $BB0_1: # =>This Inner Loop Header: Depth=1 lw $1, 8($fp) # $1 = y lw $3, 4($fp) # $3 = i addu $1, $1, $3 # y = y + i lbu $1, 0($1) # 取出y指针中的字符并保存在$1中 lw $2, 12($fp) # $2 = x addu $2, $2, $3 # x = x + i sb $1, 0($2) # 取出x指针处的字符并存放在$1中 beqz $1, $BB0_4 # if *y == 0 goto $BB0_4 nop j $BB0_3 nop $BB0_3: # in Loop: Header=BB0_1 Depth=1 lw $1, 4($fp) # 从内存中取出i的值放入$1 addiu $1, $1, 1 # i = i + 1 sw $1, 4($fp) # 将i存入内存 j $BB0_1 nop $BB0_4: move $sp, $fp # $sp = $fp lw $fp, 16($sp) # 恢复ra寄存器 lw $ra, 20($sp) # 恢复sp寄存器 addiu $sp, $sp, 24 # 释放栈空间 jr $ra nop

3.

c
// Type your code here, or load an example. void sort(char v[], int n){ int i, j; for(i = 0; i < n; i ++) for(j = i - 1; j >= 0 && v[j] > v[j + 1]; j -= 1) { int temp = v[j]; v[j] = v[j + 1]; v[j + 1] = temp; } }
plain text
sort(char*, int): # @sort(char*, int) addiu $sp, $sp, -32 sw $ra, 28($sp) # 4-byte Folded Spill sw $fp, 24($sp) # 4-byte Folded Spill move $fp, $sp sw $4, 20($fp) sw $5, 16($fp) sw $zero, 12($fp) j $BB0_1 nop $BB0_1: # =>This Loop Header: Depth=1 lw $1, 12($fp) lw $2, 16($fp) slt $1, $1, $2 beqz $1, $BB0_13 nop j $BB0_3 nop $BB0_3: # in Loop: Header=BB0_1 Depth=1 lw $1, 12($fp) addiu $1, $1, -1 sw $1, 8($fp) j $BB0_4 nop $BB0_4: # Parent Loop BB0_1 Depth=1 lw $1, 8($fp) addiu $2, $zero, 0 sw $2, 0($fp) # 4-byte Folded Spill bltz $1, $BB0_7 nop j $BB0_6 nop $BB0_6: # in Loop: Header=BB0_4 Depth=2 lw $1, 20($fp) lw $2, 8($fp) addu $1, $1, $2 lb $2, 0($1) lb $1, 1($1) slt $1, $1, $2 sw $1, 0($fp) # 4-byte Folded Spill j $BB0_7 nop $BB0_7: # in Loop: Header=BB0_4 Depth=2 lw $1, 0($fp) # 4-byte Folded Reload andi $1, $1, 1 beqz $1, $BB0_11 nop j $BB0_9 nop $BB0_9: # in Loop: Header=BB0_4 Depth=2 lw $1, 20($fp) lw $2, 8($fp) addu $1, $1, $2 lb $1, 0($1) sw $1, 4($fp) lw $1, 20($fp) lw $2, 8($fp) addu $2, $1, $2 lbu $1, 1($2) sb $1, 0($2) lw $1, 4($fp) lw $3, 20($fp) lw $2, 8($fp) addu $2, $2, $3 sb $1, 1($2) j $BB0_10 nop $BB0_10: # in Loop: Header=BB0_4 Depth=2 lw $1, 8($fp) addiu $1, $1, -1 sw $1, 8($fp) j $BB0_4 nop $BB0_11: # in Loop: Header=BB0_1 Depth=1 j $BB0_12 nop $BB0_12: # in Loop: Header=BB0_1 Depth=1 lw $1, 12($fp) addiu $1, $1, 1 sw $1, 12($fp) j $BB0_1 nop $BB0_13: move $sp, $fp lw $fp, 24($sp) # 4-byte Folded Reload lw $ra, 28($sp) # 4-byte Folded Reload addiu $sp, $sp, 32 jr $ra nop

本文由 GJJ 创作,内容来源于 Notion 数据库,随时可在 Notion 中编辑更新。 本站由 DeepSeek-v4-flash 辅助构建,项目参考 NotionNext

← 返回首页
61
文章
6
标签
3
分类
962
运行天数