lh

lh

Assembly RISC-V Referência

lyszt.net aborda lh e outras instruções RISC-V com mais detalhes.

Formato de codificação

R
31–25funct7
24–20rs2
19–15rs1
14–12funct3
11–7rd
6–0opcode
I
31–20imm[11:0]
19–15rs1
14–12funct3
11–7rd
6–0opcode
S
31–25imm[11:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:0]
6–0opcode
B
31–25imm[12,10:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:1,11]
6–0opcode
U
31–12imm[31:12]
11–7rd
6–0opcode
J
31–12imm[20,10:1,11,19:12]
11–7rd
6–0opcode

Descrição

lh carrega uma meia-palavra da memória. Um byte tem 8 bits e possui seu próprio endereço, o que o torna a menor unidade endereçável. Uma palavra tem 4 bytes, ou 32 bits, e uma meia-palavra é metade disso: 2 bytes, ou 16 bits. lh lê 16 bits onde lw lê 32. O endereçamento é igual ao de lw: um registrador base mais um deslocamento constante (veja a página lw). A forma aparece abaixo.

lh rd, offset(rs1)

Um registrador contém 32 bits, então um carregamento de 16 bits deve preencher os 16 bits restantes. lh usa extensão de sinal. Ele lê o bit mais significativo do valor de 16 bits, que marca o sinal de um número com sinal, e copia esse bit para todos os 16 bits superiores do registrador. O valor mantém seu sinal, então um -3 de 16 bits chega como um -3 de 32 bits.

Use lh para dados com sinal de 16 bits, como amostras de áudio ou leituras de sensores que podem ficar negativas. Seu parceiro lhu, com u de unsigned, preenche o topo com 0s, o que serve para dados que nunca ficam negativos. O padrão de bits 0x8000 carregado com lh se torna -32768, e carregado com lhu se torna +32768. Os bits na memória permanecem os mesmos, e o carregamento decide o significado.

O manual do RISC-V define lh como carregar um valor de 16 bits da memória e estendê-lo com sinal para 32 bits antes de armazená-lo em rd. O endereço efetivo é o registrador rs1 mais o deslocamento de 12 bits estendido com sinal. Um acesso é naturalmente alinhado quando seu endereço é divisível pelo tamanho do acesso em bytes, então um acesso a meia-palavra é alinhado em endereços pares.

Meias-palavras têm 2 bytes, então arrays delas ficam nos deslocamentos 0, 2, 4, e um ponteiro percorre-os adicionando 2.

Exemplo

.data
val: .half -5
.text
la t0, val
lh t1, 0(t0)   # t1 = -5 (sign-extended)