Как собрать и связать с ml64 в режиме true 64 бит

#hyperlink #64-bit #addressing #masm64

Вопрос:

Я работаю над переработкой старой программы masm в 64-разрядный режим x64, используя ml64 от Microsoft и ссылку на Windows 10. Компоновщик выдает ошибку в коде с РЕКСОМ.Префикс W. Опция компоновщика /LARGEADDRESSAWARE звучит как правильная вещь для полной 64-разрядной поддержки, но она жалуется. /LARADDRESSAWARE:НЕ работает, но из документации, которую я прочитал, кажется, что 32-разрядные программы могут выходить за рамки 2 ГБ, возможно, до 3 ГБ в «режиме совместимости». В документации MS не было ясности по этому поводу. Я тоже думал об этом .данные и .code могут быть неправильными для использования, поскольку в документации MS ml64 говорится, что они предназначены для 32-разрядного кода, но не говорится, как работать с 64-разрядным кодом. Но я, кажется, не могу найти способ не использовать .данные и .код и заставить все работать. В любом случае, я не хочу ограничиваться 4 ГБ, пропуская какую-либо опцию в link или ml64. Я сократил проблему до самого простого примера. Следующие сборки и ссылки:

 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  

Ответ №1:

Синтаксис эффективного адреса загрузки таков

 [base (index*scale) disp]  base = register  index = register  scale = 1,2,4,8  displacement = 8, 16 or 32-bit value.  

Перемещение «ADDR32» происходит при использовании 64-битного адреса в качестве смещения. Чтобы исправить это, попробуйте сначала ввести адрес текста в регистр. Например

 lea r9,Text lea r8,[r9 rsi]  

Комментарии:

1. Это все еще дает мне ту же ошибку ссылки при указании /LARGEADDRESSAWARE. Без /LARGEADDRESSAWARE я получаю настоящий 64-разрядный исполняемый код, способный выходить за рамки 4 ГБ памяти, потому что он действует так же, как если бы я указал /LARGEADDRESSAWARE:НЕТ?

2. ДА. В 64-разрядной версии Windows эта опция не требуется. Виртуальное адресное пространство для 64-разрядных программ составляет 256 ТБ.