Risc-V汇编代码入门

weixin_41410590 2022-05-16 14:29:56

在阅读Risc-V的汇编代码前需要一点汇编基础。

1.以下是RISC-V的汇编指示符和作用

指示符作用
.text代码段,之后跟的符号都在.text内
.data数据段,之后跟的符号都在.data内
.bss未初始化数据段,之后跟的符号都在.bss中
.section .foo自定义段,之后跟的符号都在.foo段中,.foo段名可以做修改
.align n按2的n次幂字节对齐
.balign n按n字节对齐
.globl sym声明sym未全局符号,其它文件可以访问
.string “str”将字符串str放入内存
.byte b1,…,bn在内存中连续存储n个单字节
.half w1,…,wn在内存中连续存储n个半字(2字节)
.word w1,…,wn在内存中连续存储n个字(4字节)
.dword w1,…,wn在内存中连续存储n个双字(8字节)
.float f1,…,fn在内存中连续存储n个单精度浮点数
.double d1,…,dn在内存中连续存储n个双精度浮点数
.option rvc使用压缩指令(risc-v c)
.option norvc不压缩指令
.option relax允许链接器松弛(linker relaxation,链接时多次扫描代码,尽可能将跳转两条指令替换为一条)
.option norelax不允许链接松弛
.option pic与位置无关代码段
.option nopic与位置有关代码段
.option push将所有.option设置存入栈
.option pop从栈中弹出上次存入的.option设置

2.以下是常用指令(伪指令) 更多详情可参考https://github.com/jameslzhu/riscv-card

第一栏为伪指令,第二栏为基础指令,第三栏说明伪指令的作用。基础指令是RISC-V处理器支持的指令,伪指令由基础指令组成,在汇编的时候由汇编器将伪指令转换为基础指令。

RISC-V RV32标准指令集有以下几种框架

  • R-format for register-register arithmetic/logical operations

  • I-format for register-immediate arith/logical operations and loads

  • S-format for stores

  • B-format for branches

  • U-format for 20-bit upper immediate instructions

  • J-format for jumps

  • Others: Used for OS & Syncronization

R即Reg相关;I即立即数相关;S存储相关;B分支相关;U高位数相关(因为一条32位指令中无法表示高达32位的数据);J跳转相关。

tips: about arithmetic & logical operations.

  • 逻辑右移(LSR)是将各位依次右移指定位数,然后在左侧补0,算术右移(ASR)是将各位依次右移指定位数,然后在左侧用原符号位补齐。

  • 逻辑左移与算术左移操作相同。

  • RISC-V采用小端格式(Little-Endian),即低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。


以下是C代码:

//main.c 
int add(int a, int b){
  return a + b ;
}
int main(void){
  return add(2, 3);
}

rvgcc main.c -g-g是为了反汇编时将C和汇编交差显示,方便阅读。rvobjdum -dS a.out > main.s 反汇编看到:

000000000001019c <add>:
int add(int a, int b){
   1019c:   1101          addi    sp,sp,-32      //从原来的栈顶再向下再开辟32Byte栈空间 
   1019e:   ec22          sd      s0,24(sp)      //保存 保存寄存器,
   101a0:   1000          addi    s0,sp,32       //栈底保存到fp/s0
   101a2:   87aa          mv      a5,a0          //a5=a0=2        
   101a4:   872e          mv      a4,a1          //a4=a1=3             
   101a6:   fef42623      sw      a5,-20(s0)     //a5=a0=2             
   101aa:   87ba          mv      a5,a4                                
   101ac:   fef42423      sw      a5,-24(s0)     //a5=a4=a1=3         
   return a + b ;                                                      
   101b0:   fec42703      lw      a4,-20(s0)     //a4=2                
   101b4:   fe842783      lw      a5,-24(s0)     //a5=3          
   101b8:   9fb9          addw    a5,a5,a4       //相加赋值给a5
   101ba:   2781          sext.w  a5,a5          //有符号扩展
}
   101bc:   853e          mv      a0,a5          //a5赋给返回寄存器a0
   101be:   6462          ld      s0,24(sp)
   101c0:   6105          addi    sp,sp,32       //释放子函数开辟的栈空间
   101c2:   8082          ret                    //返回到ra内容地址
​
00000000000101c4 <main>:
int main(void){
   101c4:   1141          addi    sp,sp,-16      //向下开辟16Byte栈空间
   101c6:   e406          sd      ra,8(sp)       //调用子函数前需要将ra压栈,否则子函数会覆盖ra
   101c8:   e022          sd      s0,0(sp)
   101ca:   0800          addi    s0,sp,16       //栈底保存到fp/s0
  return add(2, 3);
   101cc:   458d          li      a1,3           //参数寄存器赋值
   101ce:   4509          li      a0,2           //参数寄存器赋值
   101d0:   fcdff0ef      jal     ra,1019c <add> //跳进函数add的地址1019c,并将返回地址(pc+4)存入ra
   101d4:   87aa          mv      a5,a0          //计算结果a0 赋给a5
}
   101d6:   853e          mv      a0,a5          //赋给a0,作为main函数的返回值
   101d8:   60a2          ld      ra,8(sp)       //main函数的ra出栈
   101da:   6402          ld      s0,0(sp)       //main函数的sp出栈
   101dc:   0141          addi    sp,sp,16       //栈指针指向栈底,释放栈
   101de:   8082          ret                    //从main函数的ra返回

汇编语言参数传递的3种方法

  • 寄存器传参, 效率高,适合少量参数

  • 地址传参, 参数打包到一个结构体,讲结构体的地址传入,然后解包

  • 堆栈传参,调用前先压栈,再调用,返回从堆栈返回,也可以从寄存器返回

三种传参方法可以单独使用,也可以联合使用

354

 

 

 

 

...全文
506 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

571

社区成员

发帖
与我相关
我的任务
社区描述
软件工程教学新范式,强化专项技能训练+基于项目的学习PBL。Git仓库:https://gitee.com/mengning997/se
软件工程 高校
社区管理员
  • 码农孟宁
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧