MIPS汇编语言之常用指令介绍

「这是我参与11月更文挑战的第22天,活动详情查看:2021最后一次更文挑战」。

简介

咱们知道x86架构cpu用于PC端和工作站较多,ARM架构cpu常见于手机和单片机,那么MIPS架构的cpu主要在哪些设备可以找到它们的身影呢?

  • 中国龙芯
  • PS游戏机

学习环境搭建

寄存器

在mips中通用寄存器用$开头表示,一共有32个

| 寄存器编号 | 寄存器名 | 寄存器用途 | | :----------: | :------------------------------------------------------------ :|: -----------------------------------------------------------:| | 0 0 | zero | 永远返回0 | | 1 1 | at | 保留寄存器 | | 2 2- 3 | v 0 v0- v1 | 一般用于存储表达式或者函数的返回值(value的简写) | | 4 4- 7 | a 0 a0- a3 | 参数寄存器(Argument简写) | | 8 8- 15 | t 0 t0- t7 | 一般用于存储临时变量(temp简写) | | 16 16- 23 | s 0 s0- s7 | 存放子函数调用过程需要被保留的数据(saved values) | | 24 24- 25 | t 8 t8- t9 | 属性同 t 0 t0- t7 | | 26 26- 27 | k 0 k0- k1 | 一般存储中断函数返回值 | | 28 28 | gp | GlobalPointer简写 | | 29 29 | sp | 栈指针,指向栈顶(Stack Pointer简写) | | 30 30 | s8/ f p ( S a v e / F r a m e P o i n t e r ) 帧指针 fp | (Save / Frame Pointer)帧指针 | | 31 | $ra | 一般用于存储函数返回地址(return address简写) |

寄存器编号和别名一一对应,同一个寄存器可以有两种不同表示方法: 0 或者 0**或者** zero

  • program counter (PC) 无法直接修改,通过跳转指令可以改动
  • HI 和 LO :这两个寄存器特别用来保存乘法、除法、乘法累加的结果。

MIPS汇编中的分段处理

.data #数据段

.text #代码段
复制代码

传送指令

  1. 加载立即数指令 li

li(load immediate) :用于将立即数传送给寄存器

li $t0,1  ;十六进制数据使用0x前缀表示
复制代码
  1. 加载地址指令 la

la(load address) :用于将地址传送至寄存器中, 多用于通过地址获取数据段中的地址

.data 
msg: .ascii "hello world"

.text
la $a0,msg # 将字符串数据所在的地址赋值给$a0寄存器

复制代码
  1. 寄存器数据传送指令move

用于将一个寄存器中的数据传送至另一个寄存器当中

move $t0,$t1  # 将寄存器$t1中的数据传送至$t0
复制代码

系统服务指令 syscall

在C语言中输出文本可以使用printf函数,但是汇编中没有printf这么一说,如果想要输出文本,需要借助syscall指令

如果想要输出一个数字1,那么**syscall指令从$a0寄存器中取出需要输出的数据**

因此, 你在执行syscall指令之前需要将数据提前放入$a0之中:

li $a0,1
syscall
复制代码

同时,还需要指定输出的数据类型,数据类型的指定保存在$v0寄存器中

# $v0=1, syscall--->print_int
# $v0=4, syscall--->print_string
复制代码

$v0存入1,表示syscall$a0中的数据当做数字输出

$v0存入4,表示syscall$a0中的数据当做数据的地址,然后输出对应的数据

syscall指令读写对照表

Service Code in $v0 Arguments Result
print integer 1 $a0 = integer to print
print float 2 $f12 = float to print
print double 3 $f12 = double to print
print string 4 $a0 = address of null-terminated string to print
read integer 5 $v0 contains integer read
read float 6 $f0 contains float read
read double 7 $f0 contains double read
read string 8 a 0 = a d d r e s s o f i n p u t b u f f e r a0 = address of input buffer a1 = maximum number of characters to read See note below table
sbrk (allocate heap memory) 9 $a0 = number of bytes to allocate $v0 contains address of allocated memory
exit (terminate execution) 10
print character 11 $a0 = character to print See note below table
read character 12 $v0 contains character read
open file 13 a 0 = a d d r e s s o f n u l l t e r m i n a t e d s t r i n g c o n t a i n i n g f i l e n a m e a0 = address of null-terminated string containing filename a1 = flags $a2 = mode $v0 contains file descriptor (negative if error). See note below table
read from file 14 a 0 = f i l e d e s c r i p t o r a0 = file descriptor a1 = address of input buffer $a2 = maximum number of characters to read $v0 contains number of characters read (0 if end-of-file, negative if error). See note below table
write to file 15 a 0 = f i l e d e s c r i p t o r a0 = file descriptor a1 = address of output buffer $a2 = number of characters to write $v0 contains number of characters written (negative if error). See note below table
close file 16 $a0 = file descriptor
exit2 (terminate with value) 17 $a0 = termination result See note below table
Services 1 through 17 are compatible with the SPIM simulator, other than Open File (13) as described in the Notes below the table. Services 30 and higher are exclusive to MARS.
time (system time) 30 a 0 = l o w o r d e r 32 b i t s o f s y s t e m t i m e a0 = low order 32 bits of system time a1 = high order 32 bits of system time. See note below table
MIDI out 31 a 0 = p i t c h ( 0 127 ) a0 = pitch (0-127) a1 = duration in milliseconds a 2 = i n s t r u m e n t ( 0 127 ) a2 = instrument (0-127) a3 = volume (0-127) Generate tone and return immediately. See note below table
sleep 32 $a0 = the length of time to sleep in milliseconds. Causes the MARS Java thread to sleep for (at least) the specified number of milliseconds. This timing will not be precise, as the Java implementation will add some overhead.
MIDI out synchronous 33 a 0 = p i t c h ( 0 127 ) a0 = pitch (0-127) a1 = duration in milliseconds a 2 = i n s t r u m e n t ( 0 127 ) a2 = instrument (0-127) a3 = volume (0-127) Generate tone and return upon tone completion. See note below table
print integer in hexadecimal 34 $a0 = integer to print Displayed value is 8 hexadecimal digits, left-padding with zeroes if necessary.
print integer in binary 35 $a0 = integer to print Displayed value is 32 bits, left-padding with zeroes if necessary.
print integer as unsigned 36 $a0 = integer to print Displayed as unsigned decimal value.
(not used) 37-39
set seed 40 a 0 = i . d . o f p s e u d o r a n d o m n u m b e r g e n e r a t o r ( a n y i n t ) . a0 = i.d. of pseudorandom number generator (any int). a1 = seed for corresponding pseudorandom number generator. No values are returned. Sets the seed of the corresponding underlying Java pseudorandom number generator (java.util.Random). See note below table
random int 41 $a0 = i.d. of pseudorandom number generator (any int). $a0 contains the next pseudorandom, uniformly distributed int value from this random number generator's sequence. See note below table
random int range 42 a 0 = i . d . o f p s e u d o r a n d o m n u m b e r g e n e r a t o r ( a n y i n t ) . a0 = i.d. of pseudorandom number generator (any int). a1 = upper bound of range of returned values. $a0 contains pseudorandom, uniformly distributed int value in the range 0 = [int] [upper bound], drawn from this random number generator's sequence. See note below table
random float 43 $a0 = i.d. of pseudorandom number generator (any int). $f0 contains the next pseudorandom, uniformly distributed float value in the range 0.0 = f 1.0 from this random number generator's sequence. See note below table
random double 44 $a0 = i.d. of pseudorandom number generator (any int). $f0 contains the next pseudorandom, uniformly distributed double value in the range 0.0 = f 1.0 from this random number generator's sequence. See note below table
(not used) 45-49
ConfirmDialog 50 $a0 = address of null-terminated string that is the message to user $a0 contains value of user-chosen option 0: Yes 1: No 2: Cancel
InputDialogInt 51 $a0 = address of null-terminated string that is the message to user a 0 c o n t a i n s i n t r e a d a0 contains int read a1 contains status value 0: OK status -1: input data cannot be correctly parsed -2: Cancel was chosen -3: OK was chosen but no data had been input into field
InputDialogFloat 52 $a0 = address of null-terminated string that is the message to user f 0 c o n t a i n s f l o a t r e a d f0 contains float read a1 contains status value 0: OK status -1: input data cannot be correctly parsed -2: Cancel was chosen -3: OK was chosen but no data had been input into field
InputDialogDouble 53 $a0 = address of null-terminated string that is the message to user f 0 c o n t a i n s d o u b l e r e a d f0 contains double read a1 contains status value 0: OK status -1: input data cannot be correctly parsed -2: Cancel was chosen -3: OK was chosen but no data had been input into field
InputDialogString 54 a 0 = a d d r e s s o f n u l l t e r m i n a t e d s t r i n g t h a t i s t h e m e s s a g e t o u s e r a0 = address of null-terminated string that is the message to user a1 = address of input buffer $a2 = maximum number of characters to read See Service 8 note below table $a1 contains status value 0: OK status. Buffer contains the input string. -2: Cancel was chosen. No change to buffer. -3: OK was chosen but no data had been input into field. No change to buffer. -4: length of the input string exceeded the specified maximum. Buffer contains the maximum allowable input string plus a terminating null.
MessageDialog 55 a 0 = a d d r e s s o f n u l l t e r m i n a t e d s t r i n g t h a t i s t h e m e s s a g e t o u s e r a0 = address of null-terminated string that is the message to user a1 = the type of message to be displayed: 0: error message, indicated by Error icon 1: information message, indicated by Information icon 2: warning message, indicated by Warning icon 3: question message, indicated by Question icon other: plain message (no icon displayed) N/A
MessageDialogInt 56 a 0 = a d d r e s s o f n u l l t e r m i n a t e d s t r i n g t h a t i s a n i n f o r m a t i o n t y p e m e s s a g e t o u s e r a0 = address of null-terminated string that is an information-type message to user a1 = int value to display in string form after the first string N/A
MessageDialogFloat 57 a 0 = a d d r e s s o f n u l l t e r m i n a t e d s t r i n g t h a t i s a n i n f o r m a t i o n t y p e m e s s a g e t o u s e r a0 = address of null-terminated string that is an information-type message to user f12 = float value to display in string form after the first string N/A
MessageDialogDouble 58 a 0 = a d d r e s s o f n u l l t e r m i n a t e d s t r i n g t h a t i s a n i n f o r m a t i o n t y p e m e s s a g e t o u s e r a0 = address of null-terminated string that is an information-type message to user f12 = double value to display in string form after the first string N/A
MessageDialogString 59 a 0 = a d d r e s s o f n u l l t e r m i n a t e d s t r i n g t h a t i s a n i n f o r m a t i o n t y p e m e s s a g e t o u s e r a0 = address of null-terminated string that is an information-type message to user a1 = address of null-terminated string to display after the first string N/A

使用syscall指令输出helloworld示例:

.data 

msg: .ascii "hello world\0" #类似于C语言中 char* msg="hello world"

.text
la $a0,msg
li $v0,4
syscall
复制代码

Mips汇编指令汇总表

类别

指令名称

实例

含义

注释

英文注解

加法

add $s1,  $s2,  $s3

$s1 = $s2 + $s3

三个寄存器操作数

addition 加法

减法

sub $s1,  $s2,  $s3

$s1 = $s2 - $s3

三个寄存器操作数

subtraction 减法

立即数加法

addi $s1, $s2,  20

$s1 = $s2 + 20

用于加常数数据

add immediate 立即加法

取字

lw $s1, 20 ($s2)

$s1 = Memory[$s2 + 20]

将一个字从内存中取到寄存器中

load word 加载字

存字

sw $s1, 20 ($s2)

Memory[$s2 + 20] = $s1

将一个字从寄存器中取到内存中

store word 存储字

取半字

lh $s1, 20 ($s2)

$s1 = Memory[$s2 + 20]

将半个字从内存中取到寄存器中

load halfword 加载半字

取无符号半字

lhu $s1, 20 ($s2)

$s1 = Memory[$s2 + 20]

将半个字从内存中取到寄存器中

load halfword unsigned

存半字

sh $s1, 20 ($s2)

Memory[$s2 + 20] = $s1

将半个字从寄存器中取到内存中

stroe halfword 存储半字

取字节

lb $s1, 20 ($s2)

$s1 = Memory[$s2 + 20]

将一字节从内存中取到寄存器中

load byte

取无符号字节

lbu $s1, 20 ($s2)

$s1 = Memory[$s2 + 20]

将一字节从内存中取到寄存器中

load byte unsigned

存字节

sb $s1, 20 ($s2)

Memory[$s2 + 20] = $s1

将一字节从寄存器中取到内存中

store byte

取链接字

ll $s1, 20 ($s2)

$s1 = Memory[$s2 + 20]

取字作为原子交换的前半部

load linked

存条件字

sc $s1, 20 ($s2)

Memory[$s2 + 20] = $s1;

$s1 = 0 or 1

存字作为原子交换的后半部分

store conditional

取立即数的高位

lui $s1, 20

$s1 = 20 * 216

取立即数并放到高16位

load upper immediate

and $s1, $s2, $s3

$s1 = $s2 & $s3

三个寄存器操作数按位与

and

or $s1, $s2, $s3

$s1 = $s2 | $s3

三个寄存器操作数按位或

or

或非

nor $s1, $s2, $s3

$s1 = ~ ($s2 | $s3)

三个寄存器操作数按位或非

not or

立即数与

andi $s1, $s2, 20

$s1 = $s2 & 20

和常数按位与

and immediate

立即数或

ori $s1, $s2, 20

$s1 = $s2 | 20

和常数按位或

or immediate

逻辑左移

sll $s1, $s2, 10

$s1 = $s2 << 20

根据常数左移相应位

set left logical

逻辑右移

srl $s1, $s2, 10

$s1 = $s2 >> 20

根据常数右移相应位

set right logical

相等时跳转

beq $s1, $s2, 25

if ($s1 == $s2) go to 

PC + 4 + 25 * 4

相等检测:

和PC相关的跳转

branch on equal

不相等时跳转

bne $s1, $s2, 25

if ($s1 != $s2) go to 

PC + 4 + 25 * 4

不相等检测:

和PC相关的跳转

branch on not equal

小于时跳转

slt $1, $s2, $3

if ($s2 < $s3) $s1 = 1; 

else $s1 = 0

比较是否小于

set less than

无符号数比较小时置位

sltu $1, $s2, $3

if ($s2 < $s3) $s1 = 1; 

else $s1 = 0

比较是否小于无符号数

set less than unsigned

无符号数小于立即数时置位

slti $1, $s2, 20

if ($s2 < 20) $s1 = 1; 

else $s1 = 0

比较是否小于常数

set less than immediate

无符号数比较小于无符号立即数时置位

sltiu $1, $s2, 20

if ($s2 < 20) $s1 = 1; 

else $s1 = 0

比较是否小于无符号常数

set less than immediate unsigned

跳转

j 2500

go to 2500 * 4

跳转到目标地址

jump

跳转至寄存器所指位置

jr $ra

go to $ra

用于switch语句,以及过程调用

jump register

跳转并链接

jal 2500

$ra = PC + 4;

go to 2500 * 4;

用于过程调用(方法)

正常的执行流程执行完A自然要执行B指令,现在要跳转执行C方法,这时就把B地址存入寄存器中,执行完C后跳转到B

jump and link

Mips内存结构图:

猜你喜欢

转载自juejin.im/post/7033198915868426253
今日推荐