• RSIC-V指令及介绍(1)


    注释符号: #

    add rd, rs1, rs2        # rd = rs1 + rs2         针对寄存器操作

    add rd, rs1, x0        # rd = rs1 + x0        x0代表零号寄存器 只读 代表0 这个语句就是把rs1赋给rd    

    sub rd, rs1, rs2        # rd = rs1 - rs2         针对寄存器减法操作

    addi rd, rs1, 10        # rd = rs1 + 10         针对寄存器和立即数的加法操作

    addi rd, rs1, -10        # rd = rs1 - 10        减法也是用addi

    内存地址的存储方式有两种 即big endian(大端):低位字节存在高位字节地址上
    和 little endian(小端):低位字节存在低位字节上
    risc-v 使用的是小端

    lw rd, 12(rs)        #lw代表load word的意思 把rs作为基址寄存器加上偏移量12的值加载到rd
    load的过程是内存到寄存器

    sw rs, 40(rd)        #sw代表store word 把rs寄存器的值存到rd加偏移量40的内存地址中
    sw的过程是寄存器到内存

    lb        #load byte 将字节地址中的1字节数据符号扩展后装载到对应寄存器中
    比如1000 0000 扩展就是把最高位的1作为符号位扩展 形成0xffffff80

    lbu        #load byte unsigned 就是把填充的都用0来填充

    sb        #store byte 将寄存器中最低字节位的1字节数据保存到对应字节地址中

    跳转指令:

    beq rs1, rs2, L1        #branch if equal 如果rs1等于rs2 那么就跳转到L1

    bne        #branch if not equal 不等于跳转

    blt        #branch if less than 小于跳转

    bltu        #branch if less than unsigned 小于跳转 把寄存器看作是无符号数 

    bge        #banch if greater or equal 大于等于跳转

    j L1        #jump L1 直接跳转到L1

    逻辑运算指令:

    and rd, rs1, rs2        #rd = rs1 & rs2

    andi rd, rs1, 3        #rd = rs1 & 3

    sll        #shift left logical 逻辑左移 右边0填充

    slli rd, rs1, 2       #shift left logical immediate 逻辑 立即数左移 把rs1逻辑左移2位 右边0填充

    sra        #shift right arithmetic 算术右移指令 即移动后左边用原数最高位填充

    srai        #立即数算术右移 移动后左边用原数最高位填充

    srl        #逻辑右移 移动后左边用0来填充

    srli        #立即数逻辑右移 移动后左边用0来填充

    or        #逻辑或

    ori        #立即数逻辑或

    xor        #逻辑异或

    xori        #立即数逻辑异或 

    risc-v中也有一些伪指令 比如mv rd, rs = addi rd, rs, 0
    li rd, 13 = addi rd, x0, 13
    它们用来简化书写的语法

    通过编译得到的可执行文件 指令段和数据段分别存放在内存里的指令空间和数据空间中
    PC寄存器存放着下一条待执行指令的地址 通过不停的更新PC值来让处理器不停执行
    一般情况下是顺序执行 就是PC值加4 但是遇到分支指令的时候 就需要更新为跳转位置

    函数的调用6个基本步骤:

    1.发生函数调用时,在执行函数功能前,先将这次调用中用到的参数保存,方便取用

    2. 将控制权交给这调用的功能函数

    3.根据情况为函数申请一定的本地存储空间,以满足函数执行过程中需要的存储需求

    4.执行该函数的操作

    5.在函数执行完成后,将得到的结果数据存放好,便于主进程来获取,同时还原函数执行过程中使用到的寄存器值,释放分配给函数的本地存储空间

    6.将控制权转移给原进程

     

    zero代表x0寄存器
    通常a0 - a7 (x10 - x17)寄存器是用来向调用的函数传递参数,a0和a1寄存器常用于传递返回值
    ra,即x1寄存器,用来保存返回时的返回地址值 
    s0 - s11 对应的编号x8 - x9 和 x18 - x27的寄存器用来作为保存寄存器,保存原进程中的关键数据避免在函数调用过程中被破环

    jr        #函数调用可能发生在程序段多个位置,每次调用函数返回地址都不同 随时都会发生变化
    需要在函数调用前记录下返回地址并保存在ra寄存器中 返回时用jr指令返回到ra寄存器中保存的地址保证多次调用的灵活性

     jal        #跳转并链接 可以形成指向调用点的地址或链接,从而是函数能返回正确的地址
    跳转则会使PC跳转指向被调用函数的地址 并且将链接得到的下一指令的地址作为返回地址 保存在ra寄存器中

  • 相关阅读:
    python18 正则表达式
    thinkphp6 指令任务 宝塔定时任务
    Singularity 镜像管理工具的学习路线推荐,及学习建议
    一个高频问题:异步操作会创建线程吗?
    搭建GraphQL服务
    nodejs+vue+elementui素食主义宣传网站
    第一视角体验搭载全志T507-H的开发板MYD-YT507H开发板
    【操作系统】I/O 管理(一)—— I/O 管理概述
    面试题库(十):NIO和Netty面试题
    CVE-2016-4977 Spring远程代码执行漏洞复现 POC、EXP在文末
  • 原文地址:https://blog.csdn.net/weixin_43754049/article/details/126819600