Home > Enterprise >  Why does the MASM keyword SIZEOF MyByteArray always return 1 when using EXTERNDEF MyByteArray:BYTE
Why does the MASM keyword SIZEOF MyByteArray always return 1 when using EXTERNDEF MyByteArray:BYTE

Time:12-23

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

therecanbeonlyone

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

10bytes

Thanks!

  • Related