How to assemble and link with ml64 in true 64-bit mode (with LARGEADDRESSAWARE)?

697 Views Asked by At

I am working on reworking an old masm program to true 64-bit x64 mode using Microsoft's ml64 and link on Windows 10. The linker gives an error in code that has a REX.W prefix.

The linker's /LARGEADDRESSAWARE option sounds like the right thing for full 64 bit support, but it complains. /LARADDRESSAWARE:NO works, but from documentation I have read it seems to be an option for 32-bit programs to go beyond 2GB to maybe 3GB in "compatability mode" maybe. The MS documentation was not clear on this.

I also considered that .data and .code might be the wrong things to use because the MS ml64 documentation says that it is for 32-bit code but doesn't say how to proceed with 64-bit code. But I cannot seem to find a way to not use .data and .code and make things work. Anyway, I don't want to be limited to 4GB by missing some option in link or ml64. I have trimmed the problem down to the simplest example. The following assembles and links:

rem call "vcvars64.bat" or "vcvarsall.bat amd64" first (wherever either is located on your system)
rem using Microsoft (R) Macro Assembler (x64) Version 14.27.29112.0
    ml64 /Fl /c test.asm
rem using Microsoft (R) Incremental Linker Version 14.27.29112.0
 
rem The following works but does this really build a full over 4gb capable 64-bit executable?
rem link /entry:main /machine:x64 /LARGEADDRESSAWARE:NO test.obj  

rem The following gives a link error: "test.obj : error LNK2017: 'ADDR32' relocation to 'text' invalid without /LARGEADDRESSAWARE:NO"
    link /entry:main /machine:x64 /LARGEADDRESSAWARE test.obj     

    test.exe

The following is the test.asm program:

   .data

text    db 'xHello 64', 0

   .code

main proc

   mov rsi,1
   lea r8,[text+rsi] ; link complains with this version
;  lea r8,[text+1]   ; this works  

   ret ; I know windows should use ExitProcess but was avoiding library issues to simplify this example
main endp

   end
1

There are 1 best solutions below

5
vengy On

Load Effective Address syntax is

[base+(index*scale)+disp]

base = register 
index = register 
scale = 1,2,4,8 
displacement = 8, 16 or 32-bit value.

'ADDR32' relocation happens when using a 64bit address as an offset. To fix, try putting the address of Text into a register first. For example

lea             r9,Text
lea             r8,[r9+rsi]