Created an include file with this single externdef keyword
num.inc
EXTERNDEF MyByteArray:BYTE
Created an assembly file which defines a 10 byte array and includes num.inc
num.asm
option casemap:none
include num.inc
.data?
MyByteArray BYTE 10 DUP (?)
end
Created an assembly file which prints the size of the 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
The above files are assembled and linked with these commands below
abs.bat
@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
Everything builds great, however, when running abs.exe, it output MyByteArray = 1
I was expecting the output to be MyByteArray = 10.
(Aside: If the array is defined locally without the externdef, the output is 10)
The workaround I've used is to simply replace the SIZEOF with the actual array size
mov rax, 10
...
It's not ideal because if the array size changes, further modifications are required elsewhere to keep things in synch.
Is this behavior the result of the MASM assembler seeing the SIZEOF MyByteArray but only having access to EXTERNDEF MyByteArray:BYTE, so it returns a BYTE size of 1 instead of referencing the actual 10 byte array later on during linking?
CodePudding user response:
As suggested in the comments, define a size symbol where the array is defined
option casemap:none
include num.inc
.data?
MyByteArray BYTE 10 DUP (?)
.const
MyByteArraySize EQU SIZEOF MyByteArray
end
Then update the include file to
EXTERNDEF MyByteArray:BYTE
EXTERNDEF MyByteArraySize:ABS
Finally, in the main .asm file, reference the constant as
mov rax, MyByteArraySize
Thanks!