RISC-V汇编

2022/6/8 1:22:39

本文主要是介绍RISC-V汇编,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

ASM@RISC-V

CPU寄存器

Register ABI Discription Attribution
x0 zero 硬件常数0 N/A
x1 ra 返回地址 Caller
x2 sp 栈指针 Callee
x3 gp 全局指针 -
x4 tp 线程指针 -
x5-x7 t0-t2 临时变量 Caller
x8 s0/fp 保存寄存器/帧指针 Callee
x9 s1 保存寄存器 Callee
x10-x11 a0-a1 函数参数/返回值 Caller
x12-x17 a2-a7 函数参数 Caller
x18-x27 s2-s11 保存寄存器 Callee
x28-x31 t3-t6 临时变量 Caller
f0-f7 ft0-ft7 浮点临时变量 Caller
f8-f9 fs0-fs1 浮点保存寄存器 Callee
f10-f11 fa0-fa1 浮点函数参数/返回值 Caller
f12-f17 fa2-fa7 浮点函数参数 Caller
f18-f27 fs2-fs11 浮点保存寄存器 Callee
f28-f31 ft8-ft11 浮点临时变量 Caller

32位RISC-V(RV32)指令集概述

典型汇编语句

label: opcode operands comment
标签 操作码 操作数 注释
  • 标签:表示当前指令的位置标记
  • 操作码:
    • RISC-V标准指令
    • 伪指令
    • 用户自定义宏
  • 操作数:
    • 操作码所需的操作,与操作码之间以空格分开
    • 符号、常量、或是符号与常量组成的表达式

指令格式

  • I型指令

    imm[11:0] rs1 funct3 rd opcode
    [31:20] [19:15] [14:12] [11:7] [6:0]
  • U型指令

    imm[31:12] rd opcode
    [31:12] [11:7] [6:0]
  • S型指令

    imm[11:5] rs2 rs1 imm[4:0] rd opcode
    [31:25] [24:20] [19:15] [14:12] [11:7] [6:0]
  • R型指令

    funct7 rs2 rs1 funct3 rd opcode
    [31:25] [24:20] [19:15] [14:12] [11:7] [6:0]
  • B型指令

  • J型指令

RV32I基本指令集

算术指令

  • add

    • addi(add immediate)
  • or

    • ori(OR Immediate)
  • xor(eXclusive OR)

    • xori(eXclusive OR Immediate)
  • s

    • sll(Shift Left Logical)
      • slli(Shift Left Logical Immediate)
    • sra(Shift Right Arithmetic)
      • srai(Shift Right Arithmetic Immediate)
    • srl(Shift Right Logical)
      • srli(Shift Right Logical Immediate)
  • sub(SUBtract)

  • lui(Load Upper Immediate)
    将一个16位的立即数填入寄存器的高16位中,低16位则补零

  • auipc(Add Upper Immediate to PC)

  • slt(Set Less Than)

    • slti(Set Less Than Immediate)
      • sltiu(Set Less Than Immediate Unsigned)

加载指令

  • load

    • lb(Load Byte)
      • lbu(Load Byte Unsigned)
    • lh(Load Halfword)
      读16位,符号位拓展后写入寄存器rd中
      • lhu(Load Halfword Unsigned)
        读16位,高位补0,写入寄存器rd中
    • lw(Load Word)
      从存储器中读回一个32位的数据,写入寄存器rd中
  • store

    • sb(store Byte)
    • sh(store Halfword)
    • sw(store Word)

条件分支指令

  • branch
    • beq(branch equal)
    • bne(branch not equal)
    • bge(Branch Greater than or Equal)
      • bgeu(Branch Greater than or Equal Unsigned)
    • blt(Branch Less Than)
      • bltu(Branch Less Than Unsigned)

跳转控制指令

  • jal(Jump And Link)
    • jalr(Jump And Link Register)

寄存器屏障指令

  • fence

  • break

    • ebreak
  • call

    • ecall
  • csr

    • csrrc(Control Status Register Read & Clear bit)
      • csrrci(Control Status Register Read & Clear bit Immediate)
    • csrrs(Control Status Register Read & Set bit)
      • csrrsi(Control Status Register Read & Set bit Immediate)
    • csrrw(Control Status Register Read & Write bit)
      • csrrwi(Control Status Register Read & Write bit Immediate)

RV32标准拓展指令

RV32M标准拓展指令

  • mul
    • mulh
      • mulhsu
      • mulhu
  • div
    • divu
  • rem
    • remu

RV32A标准拓展指令

  • lr.w
  • sc.w
  • amo
    • amoswap.w
    • amoadd.w
    • amoxor.w
    • amoand.w
    • amoor.w
    • amomin.w
    • amomax.w
    • amominu.w
    • amomaxu.w

RV32F标准拓展指令

  • flw
  • fsw
  • fmadd.s
  • fmsub.s
  • fnmsub.s
  • snmadd.s
  • fadd.s
  • fsub.s
  • fmul.s
  • fdiv.s
  • fsqrt.s
  • fsgnj.s
    • fsgnjn.s
    • fsgnjx.s
  • fmin.s
  • fmax.s
  • fcvt.w.s
    • fcvt.wu.s
  • fmv.x.s
  • feq.s
  • flt.s
  • fclass.s
  • fcvt.s.w
  • fcvt.s.wu
  • fmv.s.x

伪指令

实际上是由基本指令组合而成

加载伪指令

  • la(Load Address)
    加载地址
  • ld(LoaD)
    加载全局参数

算术伪指令

  • nop
  • li(Load Immediate)
    加载立即数
  • mv(MOV)
  • not
  • neg
  • negw
  • sext
  • seqz
  • snez
  • sltz
  • sgtz

浮点算术伪指令

  • fmv.s
  • fabs.s
  • fneg.s
  • fmv.d
  • fabs.d
  • feng.d

条件分支伪指令

  • beqz
  • bnez
  • blez
  • bgez
  • bltz
  • bgtz

跳转控制伪指令

  • j
  • jal
  • jr
  • jalr
  • ret
  • tail

启动

  • .global(.globl)
    伪操作,用于定义全局符号,使链接过程中能被其他程序文件可见,类似于extern

  • .local
    伪操作,用于定义局部符号,仅当前程序文件可见

  • .file
    伪操作,用于指示汇编器该汇编程序的逻辑文件名

    opcode oprands
    .file "filename"
  • .section

    • .text
    • .data
    • .rodata
    • .bss
  • .type

  • .align

    • .balign
  • .zero

  • .byte

    • 2byte
    • 4byte
    • 8byte
  • .float

    • .double
  • .word

    • .half
    • .dword
  • .string

  • .equ

  • .weak
    伪操作,同时创建符号并定义为弱属性。如果该符号已定义,则设置此符号为弱属性

    • 在汇编程序中,符号的默认属性为强(strong)

    如果符号的属性为弱,则可无需定义具体内容,常用于预留空符号并通过汇编语法检查。当另外存在一个属性为强的同名符号实体时会自动覆盖并链接

  • .pushsection - .popsection

  • .marco - .endm

  • .comm(.common)

  • .option

注释

以符号 # 或 ; 作为分隔号,当行分隔号以后的部分会被视作注释

代指

  • rd(Register Destination)

指目标寄存器,实际代码中可以是t0、t1等

代码格式(C语言嵌套汇编)

在C语言文件中嵌入汇编代码,除对固定地址寄存器并直接进行操作外,需要将变量等参数传入汇编程序中,才能保证操作有效,想要传入参数,需要通过操作符列表来完成

关键字

  • asm
    为GCC的关键字,表示进行内联汇编操作,也可以使用前后各带两个下划线的__asm___asm_是GCC关键字asm的宏定义。

  • volatile
    或者_volatile__volatile_volatile,均为宏定义。如果添加了该关键字,则通知编译器避免对后续括号内添加汇编程序进行任何优化,以保持其原状

  • 汇编指令列表
    即需要嵌入的汇编指令,每条指令必须被双引号括起来(作为字符串),两条指令之前必须以“\n”或者“;”作为分隔符。如果没有添加分隔符,相连的字符串将会被合并成为一个字符串。内部语法与汇编程序一样

标记符号

  • %
    后面跟标签则为指定,若为数字则是从操作符列表顺序选择


  • “ ”
    引号中的限制字符串,用于约束此操作数变量的属性,常用的约束如:

    • r
      代表使用编译器自动分配的寄存器来存储该操作数变量

    • m
      字母“m”代表使用内存地址来存储该操作数变量,如果同时指明“rm”则编译器自动选择最优方案

    • =
      对于输出操作数而言,等号代表输出变量用作输出,原来的值会被新值替换,此约束不适用于输入操作数

    • +
      代表输出变量不仅作为输出,还作为输入,此约束不适用于输入操作数

  • ( )
    圆括号中填入C/C++变量或者表达式

输出操作符之间需使用逗号分割

操作符列表

  • 输出资源表
    : [ ]"=r"( ), [ ]"=r"( ), ···

  • 输入资源表
    : [ ]"r"( ), [ ]"r"( ), ···

  • 影响资源表
    : " ", "", ···

用于告知编译器当前内联汇编语句可能会对某些寄存器或内存进行修改,使得编译器在优化时将其因素考虑进去

  • 隐式表
    除了使用%[字符]中明确的符号命名指定之外,还可以使用%数字的方式进行隐含指定。从0开始,依次表示操作符列表中所有的输出操作数与输入操作数。

范例

int abc = 10,cba = 20;   
printf("%d & %d\n",abc,cba);

asm volatile(
    "mv %[da],%3\n"
    "add %2,%1,%0\n"
    "li %3,12\n"

    : [da]"=r"(abc), "=r"(cba)                 // Working
    : "r"(abc), [db]"r"(cba)                 // Working
    : "t1", "t2"//, "x7"
);

printf("%d & %d\n",abc,cba);

输出结果为:

10 20   (修改前)
40 12   (修改后)


这篇关于RISC-V汇编的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程