News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Use the MOV instruction to obtain the value in the array

Started by wanker742126, September 04, 2024, 05:35:02 PM

Previous topic - Next topic

johnsa

You are wanting something that simply isn't possible.
You're either violating PE and address-space constraints or trying to hack in 32bit code-gen into 64bit mode.

var[base+idx*scale] addressing is fully supported in 32bit mode.

it should NEVER be used in 64bit code as even when the relocation is generated it won't be compatible with PE without adding LARGEADDRESSAWARE:NO - which is a terrible idea for many reasons.

You won't find this addressing form generated by any 64bit compiler (ie. C/C++) for this reason. It also prevents the addressing from being fully RIP relative. The accepted practice in 64bit code is to use LEA and then register_base+idx*scale.

lea rdi, myArray        ; RIP relative.
mov eax, [rdi+rcx*4]

I believe NASM can generate RIP relative references like:
mov eax, [rel myArray + rcx*4]
but I'm not sure if that actually solves the L.A.W. problem as it's simply not encodable in x64. I think the only form that would work is with a fixed constant like:
mov eax, [rel myArray + 10] as the ONLY addressing mode with RIP that x64 can handle is [RIP + ofs]

See:
https://stackoverflow.com/questions/48124293/can-rip-be-used-with-another-register-with-rip-relative-addressing
https://stackoverflow.com/questions/34058101/referencing-the-contents-of-a-memory-location-x86-addressing-modes


lucho

Quotevar[base+idx*scale] addressing is fully supported in 32bit mode.

it should NEVER be used in 64bit code as even when the relocation is generated it won't be compatible with PE without adding LARGEADDRESSAWARE:NO - which is a terrible idea for many reasons.

I have the following instruction in my 64-bit heapsort implementation, tested and working in both ELF (Unix-like) and PE (Windows) variants without problems:
CMP R8,[RDI+8*R10+8]which both GAS and UASM encode as
4E 3B 44 D7 08Here, of course, RDI is the base, R10 is the index, 8 is the scale, and the other 8 is the offset (or displacement - don't know which is the correct term here).

johnsa

Yep that form is fine,

[base+idx*scale+constantofs]

the problem is that if you want to reference a symbol, like an array, then you can't use a constant in 64bit, it needs to be RIP relative which you can't encode - unless you use LAA=NO so that the symbols relative distance is restricted in the address space. Also, you can't omit the base register, so it needs a pair.