auipc

auipc

Assembly RISC-V Referência

lyszt.net aborda auipc 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

auipc significa add upper immediate to PC. Ele funciona como lui, tomando uma constante de 20 bits como parte superior de um valor. auipc adiciona esse valor ao contador de programa, que contém o endereço da instrução em execução no momento (veja a página beq). O resultado é um endereço medido em relação a onde esta instrução está na memória.

Endereços relativos resolvem um problema real. Um programa nem sempre sabe onde na memória será carregado. Código que se refere aos seus dados por endereços absolutos fixos falha quando é carregado em outro lugar. Código que calcula endereços relativos à instrução atual funciona onde quer que seja colocado. Essa propriedade é chamada de independência de posição.

auipc fornece a parte grossa de tal endereço, e uma instrução seguinte adiciona o restante fino de 12 bits. A instrução la, que carrega o endereço de um rótulo, é construída a partir desse par, e o mesmo vale para chamadas a funções distantes.

O manual do RISC-V diz que o pc atual pode ser obtido definindo a constante de auipc como 0. Um auipc seguido de um jalr pode transferir o controle para qualquer endereço pc-relativo de 32 bits, e um auipc seguido de um load ou store com um deslocamento de 12 bits pode acessar qualquer endereço de dados pc-relativo de 32 bits.

la e call existem para que você não precise escrever auipc à mão, e ele aparece frequentemente no trace do simulador e no código desmontado. Um auipc seguido de uma instrução com um pequeno deslocamento, formando um endereço juntos, é um padrão útil de reconhecer.

Exemplo

auipc t0, 1      # t0 = pc + 0x1000