【智能设备-MIPS架构初探】此文章归类为:智能设备。
MIPS交叉编译环境配置
通过下面的.sh脚本一键安装
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
sudo apt install qemu-user-static
sudo apt install qemu-system-mips
sudo apt install binfmt-support
sudo apt install gdb-multiarch
sudo apt-get install gcc-mips-linux-gnu
sudo apt-get install gcc-mipsel-linux-gnu
sudo apt-get install gcc-mips64-linux-gnuabi64
sudo apt-get install gcc-mips64el-linux-gnuabi64
|
调试第一个MIPS程序
源代码
预编译的c程序:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
int mySum(int a,int b)
{
int value=a+b;
return value;
}
int main()
{
int result=mySum(1,2);
printf("%d\n",result);
return 0;
}
|
静态编译
MIPS跟x86架构一样,MIPS程序也有32位、64位、大端序和小端序的区分,编译不同文件所需的命令如下
|
1
2
3
4
5
6
7
8
|
mipsel-linux-gnu-gcc demo.c -o demo_32_little -static -g
mips64el-linux-gnuabi64-gcc demo.c -o demo_64_little -static -g
mips-linux-gnu-gcc demo.c -o demo_32_big -static -g
mips64-linux-gnuabi64-gcc demo.c -o demo_64_big -static -g
|
用file和readelf验证编译的MIPS程序

静态编译的运行
使用qemu-xxxx-static模拟运行对应的文件即可
|
1
2
3
4
|
qemu-mipsel-static ./demo_32_little
qemu-mips-static ./demo_32_big
qemu-mips64el-static ./demo_64_little
qemu-mips64-static ./demo_64_big
|

动态编译
去掉-static参数就可以了
|
1
2
3
4
5
6
7
8
|
mipsel-linux-gnu-gcc demo.c -o demo_32_little_dy -g
mips64el-linux-gnuabi64-gcc demo.c -o demo_64_little_dy -g
mips-linux-gnu-gcc demo.c -o demo_32_big_dy -g
mips64-linux-gnuabi64-gcc demo.c -o demo_64_big_dy -g
|
同样可以用file和readelf命令查看文件详情,这里就看一下32位小端的

动态编译运行
动态编译的程序需要指定动态链接库。在ubuntu中,mips的动态依赖库安装在了/usr/目录中

如果不在,用find命令找一个这个文件夹,比如

找到动态链接库后,加上参数-L /usr/mipsel-linux-gnu就可以了
|
1
2
3
4
|
qemu-mipsel-static -L /usr/mipsel-linux-gnu ./demo_32_little_dy
qemu-mips-static -L /usr/mips-linux-gnuabi64 ./demo_32_big _dy
qemu-mips64el-static -L /usr/mips64el-linux-gnu ./demo_64_little_dy
qemu-mips64-static -L /usr/mips64-linux-gnuabi64 ./demo_64_big_dy
|
以动态链接的32位小端为例

调试
以demo_32_little为例,首先命令行输入qemu-mipsel -g 2234 ./demo_32_little在2234端口运行。

再打开另一个命令行,打开gdb-multiarch调试工具,依次输入
|
1
2
3
|
set architecture mips
set endian little
target remote localhost:2234
|

成功进入调试界面。

32位MIPS架构入门
MIPS寄存器
在调试界面输入info registers查看该程序中的寄存器

比x86多很多,我们分为两类,一类是通用寄存器(黄色部分),一类是特殊寄存器。
通用寄存器
| 寄存器编号 |
寄存器名称 |
全称 |
说明 |
| $0 |
zero |
常量寄存器(Constant Value 0) |
常数值,永远为0 |
| $1 |
$at |
汇编临时寄存器(Assembly Temporary) |
用于处理在16位以上的大常数时使用 |
|
2 \~3 |
v0 \~v1 |
value |
用于存储函数或者函数返回的值 |
|
4 \~7 |
a0 \~a3 |
Arguments |
存放函数调用时的参数 |
|
8 \~15 |
t0 \~t7 |
Temporary variable |
存放临时变量 |
|
16 \~23 |
s0 \~s7 |
保存寄存器(saved) |
函数调用和返回时需要保存寄存器的值 |
|
24 \~25 |
t8 \~t9 |
Temporary variable |
存放临时变量 |
|
26 \~27 |
k0 \~k1 |
Keep |
保存异常处理和中断的返回值 |
| $28 |
$gp |
全局指针(Global Pointer) |
略 |
| $29 |
$sp |
堆栈指针(Stack Pointer) |
指向栈顶 |
| $30 |
fp或s8 |
栈帧指针(Frame Pointer) 或有时候会作用第九个saved寄存器 |
一般我们把它看作$fp,但有时候他也会作为$s8,比如“实例分析:demo_32_little”中的这条汇编指令sw $fp,0x20($sp)
|
| $31 |
$ra |
Return Address |
保存函数的返回地址 |
特殊寄存器
这里先介绍三个:lo、hi和$pc:
| 寄存器名称 |
全称 |
功能 |
| $pc |
程序计数器(Program Counter |
下一条要执行的指令的地址(类似6中的eip) |
| $hi |
高 32 位寄存器(High register) |
用于乘法(mult、multu)和除法(div、divu)运算。乘法运算时,hi保存结果的高32位;除法运算时,hi 保存余数。 |
| $lo |
低 32 位寄存器(Low register) |
用于乘法(mult、multu)和除法(div、divu)运算。乘法运算时,lo保存结果的低32位;除法运算时,lo 保存商。 |
更多【智能设备-MIPS架构初探】相关视频教程:www.yxfzedu.com