Posted by m0rpheu5 on Mon, 28 Feb 2022 13:12:05 +0100

Exercise: learn the usage of LA/LB/LD/LH/LHU instruction

```#
# Learn the usage of la and lb instructions:
# 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 s2, msg
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]

slli a1, a1, 3 # a1*8
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
slli a1, a1, 2 # a1*4
lh a0, 0(s1)
ret

#
# Function unsigned int load_isa_lhu(unsigned int *array, int index)
#
slli a1, a1, 2 # a1*4
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:
#
.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