Linux操作系统lab1
1.前期准备
在linux虚拟机上安装工具,从git上下载
git clone --recursive https://github.com/riscv/riscv-gnu-toolchain
sudo apt-get install autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev
2.编译
./configure --prefix=/opt/riscv --enable-multilib
make
编译完成后,将编译工具目录写入PATH:
export PATH="$HOME/riscv/bin:$PATH"
3.测试代码
编写测试代码test.c
#include<stdio.h>
int g(int x)
{
return x+3;
}
int f(int x)
{
return g(x);
}
int main(void)
{
return f(8)+1;
}
编译生成汇编代码
riscv64-unknown-elf-gcc -S riscv-test.c -o riscv-test.s
g:
addi sp,sp,-32 # 分配栈空间sp=sp-32
sd s0,24(sp) # 把s0保存到sp+24
addi s0,sp,32 # s0指向栈底,s0=sp+32
mv a5,a0 # a5=a0中的值
sw a5,-20(s0) #
lw a5,-20(s0) #
addiw a5,a5,3 # a5=a5+3
sext.w a5,a5 # 将a5标记为扩展字
mv a0,a5 # 将a5的值返回a0
ld s0,24(sp) # 恢复s0
addi sp,sp,32 # 恢复sp
jr ra # 函数返回
f:
addi sp,sp,-32 # 分配栈空间sp=sp-32
sd ra,24(sp) # 将ra保存到sp+24
sd s0,16(sp) # 将s0保存到sp+16
addi s0,sp,32 # s0指向栈底,s0=sp+32
mv a5,a0 # a5=a0
sw a5,-20(s0) #
lw a5,-20(s0) #
mv a0,a5 # 将a5的值返回a0
call g # 调用函数g
mv a5,a0 # a5=a0
mv a0,a5 # 将a5中的值移入返回值a0中
ld ra,24(sp) # 恢复ra
ld s0,16(sp) # 恢复s0
addi sp,sp,32 # 恢复sp
jr ra # 跳转到ra地址返回
main:
addi sp,sp,-16 # 分配栈空间sp=sp-16
sd ra,8(sp) # 将ra值保存到sp+8
sd s0,0(sp) # 将s0值保存到sp+0
addi s0,sp,16 # s0指向栈底,s0=sp+16
li a0,8 # a0=8
call f # 调用函数f
mv a5,a0 # 将返回来的值a0移入a5中
addiw a5,a5,1 # a5=a5+1,按word加
sext.w a5,a5 # 将a5标记为扩展字(Sign extend word)
mv a0,a5 # 将a5的值返回a0
ld ra,8(sp) # 恢复ra
ld s0,0(sp) # 恢复s0
addi sp,sp,16 # 恢复sp
jr ra # 跳转到ra地址返回