为什么使用 EXTERNDEF MyByteArray:BYTE 时 MASM 关键字 SIZEOF MyByteArray 始终返回 1

ven*_*ngy 5 x86 assembly masm

使用这个单一 externdef 关键字创建了一个包含文件

编号.inc

EXTERNDEF MyByteArray:BYTE
Run Code Online (Sandbox Code Playgroud)

创建了一个定义 10 字节数组并包含 num.inc 的汇编文件

数字asm

option casemap:none

include num.inc

.data?
MyByteArray BYTE 10 DUP (?)

end
Run Code Online (Sandbox Code Playgroud)

创建了一个打印 MyByteArray 大小的汇编文件

ABS.ASM

option casemap:none

include num.inc

extrn printf:proc

.data
     szArray db 'MyByteArray = %d',0ah,0
     
.code

main proc
     mov     rax, SIZEOF MyByteArray
     mov     rdx,rax 
     mov     rcx,offset szArray
     sub     rsp,20h
     call    printf
     add     rsp,20h

     ret
main endp

end
Run Code Online (Sandbox Code Playgroud)

上面的文件使用下面的这些命令进行组装和链接

绝对值蝙蝠

@echo on

if not defined DevEnvDir (
  call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\VC\Auxiliary\Build\vcvars64.bat"
)

ml64.exe abs.asm num.asm /link /subsystem:console /defaultlib:kernel32.lib /defaultlib:libcmt.lib
Run Code Online (Sandbox Code Playgroud)

一切都构建得很好,但是,当运行abs.exe时,它输出MyByteArray = 1

只可以有一个人

我期望输出为MyByteArray = 10
(旁白:如果数组是在没有 externdef 的情况下本地定义的,则输出为 10)

我使用的解决方法是简单地将 SIZEOF 替换为实际数组大小

mov     rax, 10
...
Run Code Online (Sandbox Code Playgroud)

这并不理想,因为如果数组大小发生变化,则需要在其他地方进行进一步修改以保持同步。

此行为是否是 MASM 汇编器看到SIZEOF MyByteArray但只能访问EXTERNDEF MyByteArray:BYTE的结果,因此它返回 BYTE 大小 1,而不是稍后在链接期间引用实际的 10 字节数组?

ven*_*ngy 5

按照注释中的建议,在定义数组的地方定义一个大小符号

option casemap:none
include num.inc
.data?
MyByteArray BYTE 10 DUP (?)
.const
MyByteArraySize EQU SIZEOF MyByteArray
end
Run Code Online (Sandbox Code Playgroud)

然后将包含文件更新为

EXTERNDEF MyByteArray:BYTE
EXTERNDEF MyByteArraySize:ABS
Run Code Online (Sandbox Code Playgroud)

最后,在主 .asm 文件中,将常量引用为

 mov     rax, MyByteArraySize
Run Code Online (Sandbox Code Playgroud)

10字节

谢谢!