The answer to the specific question that you asked is: not directly through the UI, but it's possible with a plugin. Sample plugin #18 in the Hex-Rays SDK. The comment at the top of the plugin says:
* It shows how to specify a register value at a desired location.
* Such a functionality may be useful when the code to decompile is
* obfuscated and uses opaque predicates.
However, there's a better answer to your question. The assembly code that you displayed is commonly generated by MSVC when accessing global arrays or data structures on x64. Basically, one register will be set to the base address of the containing module (
rax in your snippet above), and then array accesses will be encoded as
r64 is some register being used for indexing purposes.
Hex-Rays trips over snippets like this one, but there is a way to fix it: namely, by turning the numeric offset in the memory expression into an RVA. As far as I know, there's currently no way to do that through the GUI (EDIT: in the comments below, Igor Skochinsky informs us how to do this through the GUI), but you can do it through a small IDAPython script.
def make_rva(ea, n):
idaapi.op_offset(ea, n, ida_nalt.REFINFO_RVAOFF | ida_nalt.REF_OFF64, idaapi.BADADDR, idaapi.get_imagebase(), 0)
Now, you can run the
make_rva function by providing the address of the instruction with the memory expression as the first argument. The second argument is the operand number: 0 for left-hand side, 1 for right-hand side. Here's an example from a database I have open. Before:
0000000180019AEC cmp byte ptr [rcx+rdx+138C84h], 0
0000000180019AEC cmp rva stru_180138C80.sectors_per_cluster[rcx+rdx], 0
I recently released a database of a malware sample that I had analyzed exhaustively, where I used these tricks as part of the analysis. You can get the database here, and then jump to address
0000000180014607 to check out the effects.
EDIT, 08/24/2021: I reported the issue discussed above to Hex-Rays, who fixed it as of 7.6.