如何在 ml64.exe 中设置对齐 64?
How to set align 64 in ml64.exe?
使用 ml64.exe
为某些汇编函数代码设置 align 64
的最简单方法是什么?
_TEXT
的默认对齐是 16,所以 ml64
不允许在 align
命令中设置超过 16。
ml64
不允许更改 _TEXT
.
的对齐方式
可以创建另一个 section/segment,但我们能否在主要 _TEXT
部分获得 64 byte
对齐?
有什么解决办法吗?
P.S。
在 _TEXT$FOO
的回答中建议的解决方案有效!
_TEXT$FOO SEGMENT ALIGN(64)
align 64
_TEXT$FOO ENDS
我还尝试在十六进制编辑器中的 obj (coff) 文件中更改 header 部分 Characteristics
中对齐字段的值,以便 _TEXT
。链接器使用了更改的对齐方式。那么,如果链接器可以使用 obj 文件中该字段的任何值,为什么 ml 和 jwasm 不允许更改 _TEXT
的默认 16 字节?
64 字节对齐在某些情况下对代码很有用。
如果您使用 16 字节对齐,那么另一个代码(可以是 C
代码)可以随机移动您的 asm
代码以获得 4 个不同的偏移量:0、16、32、48。
有些循环可能会跨越 64 字节或 32 字节的范围。因此,当您仅更改另一个 C
代码时,您会看到 asm
代码的一些不可预测的性能变化。
正如您所说,显然 ml64
(Microsoft 宏汇编程序 (x64))不允许您更改 .text
部分的对齐方式,因此您不能在其中包含任何内容大于 16 字节的对齐方式。然而,这个问题有一个简单的解决方法,那就是使用 PECOFF 的分组部分功能。如果一个节的名称中有美元符号 $
,则在链接时将忽略 $
之后的所有内容,以便将 $
之前具有相同前缀的所有节合并为一个节。合并的部分按完整部分名称排序,包括 $
.
之后的内容
例如你可以这样做:
_TEXT$FOO SEGMENT ALIGN(64)
int 3
ALIGN 64
PUBLIC function
function:
ret
_TEXT$FOO ENDS
_TEXT SEGMENT
PUBLIC start
start:
call function
int 3
_TEXT ENDS
END
在上面的示例中,_TEXT
和 _TEXT$FOO
部分将被链接器合并为一个 .text
部分。 _TEXT$FOO
中的代码将在 _TEXT
中的代码之后。
请注意,如果您真的想对齐只读数据,而不是实际代码,那么您应该将数据放在 .rdata
部分。像这样:
_RDATA SEGMENT ALIGN(64) ALIAS(".rdata") READONLY
DB 1h
ALIGN 64
PUBLIC readonlydata
readonlydata:
DB 0ffh
_RDATA ENDS
请注意,您必须在此处使用 ALIAS(".rdata")
选项,因为汇编程序不会像翻译 _TEXT
和 _DATA
到 .text
和 .data
.
使用 ml64.exe
为某些汇编函数代码设置 align 64
的最简单方法是什么?
_TEXT
的默认对齐是 16,所以 ml64
不允许在 align
命令中设置超过 16。
ml64
不允许更改 _TEXT
.
可以创建另一个 section/segment,但我们能否在主要 _TEXT
部分获得 64 byte
对齐?
有什么解决办法吗?
P.S。
在 _TEXT$FOO
的回答中建议的解决方案有效!
_TEXT$FOO SEGMENT ALIGN(64)
align 64
_TEXT$FOO ENDS
我还尝试在十六进制编辑器中的 obj (coff) 文件中更改 header 部分 Characteristics
中对齐字段的值,以便 _TEXT
。链接器使用了更改的对齐方式。那么,如果链接器可以使用 obj 文件中该字段的任何值,为什么 ml 和 jwasm 不允许更改 _TEXT
的默认 16 字节?
64 字节对齐在某些情况下对代码很有用。
如果您使用 16 字节对齐,那么另一个代码(可以是 C
代码)可以随机移动您的 asm
代码以获得 4 个不同的偏移量:0、16、32、48。
有些循环可能会跨越 64 字节或 32 字节的范围。因此,当您仅更改另一个 C
代码时,您会看到 asm
代码的一些不可预测的性能变化。
正如您所说,显然 ml64
(Microsoft 宏汇编程序 (x64))不允许您更改 .text
部分的对齐方式,因此您不能在其中包含任何内容大于 16 字节的对齐方式。然而,这个问题有一个简单的解决方法,那就是使用 PECOFF 的分组部分功能。如果一个节的名称中有美元符号 $
,则在链接时将忽略 $
之后的所有内容,以便将 $
之前具有相同前缀的所有节合并为一个节。合并的部分按完整部分名称排序,包括 $
.
例如你可以这样做:
_TEXT$FOO SEGMENT ALIGN(64)
int 3
ALIGN 64
PUBLIC function
function:
ret
_TEXT$FOO ENDS
_TEXT SEGMENT
PUBLIC start
start:
call function
int 3
_TEXT ENDS
END
在上面的示例中,_TEXT
和 _TEXT$FOO
部分将被链接器合并为一个 .text
部分。 _TEXT$FOO
中的代码将在 _TEXT
中的代码之后。
请注意,如果您真的想对齐只读数据,而不是实际代码,那么您应该将数据放在 .rdata
部分。像这样:
_RDATA SEGMENT ALIGN(64) ALIAS(".rdata") READONLY
DB 1h
ALIGN 64
PUBLIC readonlydata
readonlydata:
DB 0ffh
_RDATA ENDS
请注意,您必须在此处使用 ALIAS(".rdata")
选项,因为汇编程序不会像翻译 _TEXT
和 _DATA
到 .text
和 .data
.