rs2, off(rs1)mem[rs1 + off] = rs2sh stores a halfword — 16 bits, or 2 bytes — to memory. It is the store counterpart to the lh/lhu loads, writing the narrower size rather than the full word that sw writes. The form is sh rs2, offset(rs1): take the value in source register rs2 and write its lowest 16 bits to the address in base register rs1 plus the offset (the same store layout as sw, with the source register named first).
A register is 32 bits but only 16 are stored, so sh keeps the lowest 16 and simply drops the upper 16. Notice there is no signed-versus-unsigned choice on stores — that distinction only arose on loads, where the narrow value had to be widened to fill a register and the missing bits needed a rule. Storing goes the other way, narrowing, which has only one sensible behavior: keep the low bits. If the register held a value too big for 16 bits, those extra bits are silently lost, so checking the range is your responsibility before storing.
sh is the writer for every 16-bit format that lh and lhu read back: audio samples, 16-bit pixel data, halfword arrays. A common pattern is read-modify-write — load a halfword with lhu, adjust it in the register, then sh it back. Only the targeted 2 bytes change; the bytes around them are left untouched. Halfwords sit 2 bytes apart, so loops step the address by 2.