571
社区成员
发帖
与我相关
我的任务
分享将一个简单的C程序汇编成LoongArch或RISC-V汇编代码,并逐步分析程序的执行过程,深入理解存储程序计算机和函数调用堆栈框架在执行过程中所起的作用。
sudo apt install gcc-riscv64-linux-gnu
#include <stdio.h>
int add(int a, int b){
int ret = a + b;
return ret;
}
int main(){
int a = 1, b = 2;
int ret = 0;
ret = add(1, 2);
return 0;
}
//编译器将C源代码包括头文件stdio.h进行链接,得到test.i
riscv64-linux-gnu-gcc -E lab1.c -o lab1.i
//Gcc把test.i代码翻译成汇编语言,输出为test.s
riscv64-linux-gnu-gcc -S lab1.i -o lab1.s
.file "lab1.c"
.option pic
.text
.align 1
.globl add
.type add, @function
add:
addi sp,sp,-48 // (13)修改栈指针sp=sp-48,push
sd s0,40(sp) // (14)把s0保存到sp+40
addi s0,sp,48 // (15)栈底保存s0,s0=sp+48
mv a5,a0 // (16)a5=a0
mv a4,a1 // (17)a4=a1
sw a5,-36(s0) // (18)将a5的值保存到s0-36
mv a5,a4 // (19)a5=a4
sw a5,-40(s0) // (20)将a5的值保存到s0-40
lw a5,-36(s0) // (21)将s0-36的值写入a5
mv a4,a5 // (22)a4=a5
lw a5,-40(s0) // (23)将s0-40的值写入a5
addw a5,a4,a5 // (24)a5=a4 + a5
sw a5,-20(s0) // (25)将a5的值保存到s0-20
lw a5,-20(s0) // (26)将s0-20的值写入a5
mv a0,a5 // (27)a0=a5
ld s0,40(sp) // (28)将sp+40的值写入s0
addi sp,sp,48 // (29)sp=sp + 48
jr ra // (30)跳转到ra地址返回
.size add, .-add
.align 1
.globl main
.type main, @function
main:
addi sp,sp,-32 // (1)修改栈指针sp=sp-32,push
sd ra,24(sp) // (2)把ra保存到sp+24
sd s0,16(sp) // (3)把s0保存到sp+16
addi s0,sp,32 // (4)栈底保存s0,s0=sp+32
li a5,1 // (5)将值1写入到a5中
sw a5,-28(s0) // (6)将a5的值保存到s0-28
li a5,2 // (7)将值2写入到a5中
sw a5,-24(s0) // (8)将a5的值保存到s0-24
sw zero,-20(s0) // (9)将0保存到s0-20
li a1,2 // (10)将值1写入到a1中
li a0,1 // (11)将值2写入到a0中
call add // (12)保存现场,压栈pc指针,调用add函数
mv a5,a0 // (31)将返回来的值a0移入a5中
sw a5,-20(s0) // (32)将a5的值保存到s0-20
li a5,0 // (33)将值0写入到a5中
mv a0,a5 // (34)a0=a5
ld ra,24(sp) // (35)将sp+24的值写入ra
ld s0,16(sp) // (36)将sp+16的值写入s0
addi sp,sp,32 // (37)sp=sp + 32
jr ra // (38)跳转到ra地址返回
.size main, .-main
.ident "GCC: (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0"
.section .note.GNU-stack,"",@progbits