1

我正在使用 Microsoftml64和 Windows 10 上的链接将旧的 masm 程序改造成真正的 64 位 x64 模式。链接器在具有 REX.W 前缀的代码中给出错误。

链接器的/LARGEADDRESSAWARE选项听起来像是完整的 64 位支持的正确选择,但它抱怨。 /LARADDRESSAWARE:NO有效,但从我读过的文档来看,它似乎是 32 位程序在“兼容模式”下超过 2GB 到 3GB 的一个选项。MS 文档对此并不清楚。

.data我也认为这.code可能是错误的使用方法,因为 MS ml64 文档说它适用于 32 位代码,但没有说明如何处理 64 位代码。但我似乎无法找到一种不使用.data并使.code事情正常的方法。无论如何,我不想因缺少链接或 ml64 中的某些选项而被限制为 4GB。我已将问题简化为最简单的示例。以下汇编和链接:

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

下面是 test.asm 程序:

   .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
4

1 回答 1

0

加载有效地址语法为

[base+(index*scale)+disp]

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

当使用 64 位地址作为偏移量时,会发生“ADDR32”重定位。要解决此问题,请先尝试将 Text 的地址放入寄存器。例如

lea             r9,Text
lea             r8,[r9+rsi]
于 2021-11-12T00:35:23.400 回答