寄存器:
指令格式:
- op: 指令的基本操作,通常称为操作码(opcode)
- rs:第一个源操作数寄存器
- rt:第二个源操作数寄存器
- Rd:用于存放操作结果的目的寄存器
- shamt:位移量
- funct:功能
R-Format(Register)
I-Format(Immediate)
J-Format(Jump)
内存空间:
寻址方式:
- 立即数寻址 - I:操作数是位于指令自身中的常数
- 寄存器寻址 - R:操作数是寄存器
- 基寻址址或偏移寻址 - I:操作数在存储器中,其地址是指令中寄存器与常数的和
- PC相对寻址 - I:地址是PC+4与指令中常数的和
- 伪直接寻址 - J:跳转地址与指令中的26位字段和PC的高位拼接而成
数据定义:
- 在MIPS汇编语言中,数据定义是用来声明数据的类型和存储空间的指令。
- 可能会有选择的位数据分配名字(标签)
- 语法:
- 所有的初始值在内存中以二进制存储
- 可以类比数据类型
数据伪指令
如果初始值超过了值域上限汇编程序会报错
系统调用:
- 程序通过系统调用实现输入/输出
- mips提供一条特殊的syscall指令
- 使用syscall系统服务
- syscall服务:
程序模板:
# 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.
int square(int i, int j, int h, int g) {
int f;
f = (g + h) - (i + j);
return f;
}# 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 # 返回
nop2.
void strcpy(char x[], char y[]){
int i;
i = 0;
while((x[i] = y[i]) != '\0')
i += 1;
}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
nop3.
// 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;
}
}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