Load instruction
Instruction name | function | ISA | type | usage | meaning |
LA | Address loading, pseudo instruction | RV32I/RV64I | Pseudo instruction | la rd, symbol | Load the address of the symbol into x[rd]. When compiling location independent code, it is extended to the global offset table (Global Offset Table). For RV32I, it is equivalent to executing auipc rd, offsetHi, and then lw rd, offsetLo(rd); For RV64I, it is equivalent to auipc rd, offsetHi and ld rd, offsetLo(rd). If the offset is too large, The first instruction to calculate the load address will become two, first auipc rd, offsetHi, and then addi Rd, RD, and offsetlo |
LI | Immediate load, | RV32I/RV64I | Pseudo instruction | li rd, immediate | Load constants into x[rd] with as few instructions as possible. In RV32I, it is equivalent to executing lui and / or addi; yes In RV64I, it will be extended to this instruction sequence Lui, addi, slli, addi, slli, addi, slli, addi. |
LLA | Local address loading, pseudo instruction | RV32I/RV64I | Pseudo instruction | lla rd, symbol | Load the address of the symbol into x[rd]. It is equivalent to executing auipc rd, offsetHi, and then addi rd, rd, offsetLo. |
LB | Byte loading | RV32I/RV64I | I | lb rd, offset(rs1) | Read a byte from address x [RS1] + sign extend (offset) and write it to x[rd] after symbol bit expansion. |
LBU | Unsigned byte loading | RV32I/RV64I | I | lbu rd, offset(rs1) | Read a byte from the address x [RS1] + sign extend (offset) and write it to x[rd] after zero expansion. |
LH | Half word loading | RV32I/RV64I | I | lh rd, offset(rs1) | Read two bytes from address x [RS1] + sign extend (offset), and write x[rd] after symbol bit expansion. |
LHU | Unsigned halfword loading | RV32I/RV64I | I | lhu rd, offset(rs1) | Read two bytes from address x [RS1] + sign extend (offset), and write x[rd] after zero expansion. |
LD | Double word loading | RV32I/RV64I | I | ld rd, offset(rs1) | Read eight bytes from address x [RS1] + sign extend (offset) and write x[rd]. |
LR.D | Load reserved doubleword | RV64A | R | lr.d rd, (rs1) | Load eight bytes from the memory address x[rs1], write x[rd], and reserve the memory doubleword registration |
LW | Word loading | RV32I/RV64I | I | lw rd, offset(rs1) | Read four bytes from address x [RS1] + sign extend (offset) and write x[rd]. For RV64I, the results are signed Bit extension. |
LR.W | Load reserved words | RV32A/RV64A | R | lr.w rd, (rs1) | Load four bytes from the address x[rs1] in memory, write x[rd] after symbol bit expansion, and register and reserve this memory word. |
LWU | Unsigned word loading | RV64I | I | lwu rd, offset(rs1) | Read four bytes from address x [RS1] + sign extend (offset), and write x[rd] after zero expansion. |
LUI | High immediate load | RV32I/RV64I | U | lui rd, immediate | Shift the sign bit extended 20 bit immediate to the left by 12 bits, and write the low 12 position zero into x[rd]. |
Exercise: learn the usage of LA/LB/LD/LH/LHU instruction
# # Learn the usage of la and lb instructions: # Function char load_isa_la_lb(int index) # Function meaning: # la loads the address of msg into the s2 register, and the parameter index is represented by a0 in the assembly # Then use the lb instruction to read the index byte of msg string, and the return value is stored in a0. # Summary: # la address loading instruction, pseudo instruction, usage la rd, symbol, load symbol into x[rd] register # lb byte loading instruction, lb rd, offset(rs1), read a byte from address x [RS1] + sign extend (offset) .globl load_isa_la_lb load_isa_la_lb: la s2, msg add s3, s2, a0 lb a0, 0(s3) ret # # Function unsigned long load_isa_ld(unsigned long *array, int index) # Function meaning: # Returns the value of array[index]. # The value of array is stored in register a0 and the value of index is stored in register a1 # slli logical shift left instruction shifts the value of index by 3 bits to the left, which is equivalent to multiplying by 8 # Summary: # 1. In the compilation, index is only a numerical value and will not be intelligently converted into array[index], # You must convert it to array+8*index to get the value of array[index] # 2. The LD instruction is a double word loading instruction in the format of LD, RD, offset (RS1) # Read 8 bytes from address x [RS1] + sign extend (offset) and write x[rd] .globl load_isa_ld load_isa_ld: slli a1, a1, 3 # a1*8 add s1, a0, a1 ld a0, 0(s1) ret # # Function unsigned int load_isa_lh(unsigned int *array, int index) # load_isa_lh and load_ isa_ The lhu function is used to compare lh and lhu instructions # LH: LH Rd offset (RS1) half word loading instruction, read 2 bytes from address x [RS1] + sign extend (offset), and write x[rd] after symbol bit expansion # lhu: lhu rd offset(rs1) unsigned halfword loading instruction, read 2 bytes from address x [RS1] + sign extend (offset), and write x[rd] after symbol bit expansion .globl load_isa_lh load_isa_lh: slli a1, a1, 2 # a1*4 add s1, a0, a1 lh a0, 0(s1) ret # # Function unsigned int load_isa_lhu(unsigned int *array, int index) # .globl load_isa_lhu load_isa_lhu: slli a1, a1, 2 # a1*4 add s1, a0, a1 lhu a0, 0(s1) ret .section .data msg: .string "Hello, world!\n"
Storage instruction
Instruction name | function | ISA | type | usage | meaning |
SD | Save double word | RV64I | S | sd rs2, offset(rs1) | Store the 8 bytes in x[rs2] into the memory address x [RS1] + sign extend (offset). |
SC.D | Conditional deposit double word | RV64A | R | sc.d rd, rs2, (rs1) | If there is a load reservation on the memory address x[rs1], store the number of 8 bytes in the x[rs2] register in that address. If deposited If successful, store 0 in register x[rd], otherwise store a non-0 error code |
SW | Save word | RV32I/RV64I | S | sw rs2, offset(rs1) | Store the lower 4 bytes of x[rs2] into the memory address x [RS1] + sign extend (offset). |
SC.W | Conditional deposit word | RV32A/RV64A | R | sc.w rd, rs2, (rs1) | There is a load reservation on the memory address x[rs1], and the number of 4 bytes in the x[rs2] register is stored in this address. If the deposit is successful, Store 0 in register x[rd], otherwise store a non-0 error code. |
SH | Save half word | RV32I/RV64I | S | sh rs2, offset(rs1) | Store the lower two bytes of x[rs2] into the memory address x [RS1] + sign extend (offset). |
SB | Memory byte | RV32I/RV64I | S | sb rs2, offset(rs1) | Store the low byte of x[rs2] into the memory address x [RS1] + sign extend (offset). |
Exercise: Learn SD/SW/SH/SB instructions
# # unsigned long store_isa_sd(unsigned long *addr, unsigned long v) # Function meaning: # Store v in the address addr, and then read the value of the data in addr memory and return # .globl store_isa_sd store_isa_sd: sd a1, 0(a0) ld a0, 0(a0) ret # unsigned int store_isa_sd(unsigned int *addr, unsigned int v) .globl store_isa_sw store_isa_sw: sw a1, 0(a0) lw a0, 0(a0) ret # unsigned short store_isa_sd(unsigned short *addr, unsigned short v) .globl store_isa_sh store_isa_sh: sh a1, 0(a0) lh a0, 0(a0) ret # unsigned char store_isa_sd(unsigned short *char, unsigned char v) .globl store_isa_sb store_isa_sb: sb a1, 0(a0) lb a0, 0(a0) ret
Note that LR/SC can be used to construct lock free data structures.
Compare exchange functions as follows:
# a0 holds address of memory location # a1 holds expected value # a2 holds desired value # a0 holds return value, 0 if successful, !0 otherwise cas: lr.w t0, (a0) bne t0, a1, fail sc.w t0, a2, (a0) bnez t0, cas li a0, 0 jr ra fail: li a0, 1 jr ra # Load original value. # Doesn't match, so fail. # Try to update. # Retry if store-conditional failed. # Set return to success. # Return. # Set return to failure. # Return.