If you try to declare an array longer than 512 characters, MASM issues an error:
error A2039:line too long
How to declare big array for MASM? One large array is needed, not several small ones.
Breaking into several lines, inserting the character ‘ ‘ does not solve the problem.
In this case, it is an array of structures:
.data
sysmet struc
iIndex DB 0
szLabel DB 22 DUP (0)
zero1 DB 0
szDesc DB 40 DUP (0)
zero2 DB 0
sysmet ends
sysm sysmet <SM_CXSCREEN, "SM_CXSCREEN", 0, "Screen width in pixels", 0>,
<SM_CYSCREEN, "SM_CYSCREEN", 0, "Screen height in pixels", 0>,
<SM_CXVSCROLL, "SM_CXVSCROLL", 0, "Vertical scroll width", 0>,
<SM_CYHSCROLL, "SM_CYHSCROLL", 0, "Horizontal scroll height", 0>,
<SM_CYCAPTION, "SM_CYCAPTION", 0, "Caption bar height", 0>,
<SM_CXBORDER, "SM_CXBORDER", 0, "Window border width", 0>,
<SM_CYBORDER, "SM_CYBORDER", 0, "Window border height", 0>,
<SM_CXFIXEDFRAME, "SM_CXFIXEDFRAME", 0, "Dialog window frame width", 0>
The number of characters in the array declaration reaches 552.
If you remove the last line, the error does not appear.
If added a ‘sysmet’, then the
lengthof sysm
operator returns the number of elements to the first sysmet. This does not suit me. I need to declare an array of large size for which both the number of elements and the size of the structure as a whole will be counted correctly.
The only solution I found at the moment is the initialization of an empty array through the DUP. Then fill in the elements of the array when processing the WM_CREATE message.
sysm sysmet 74 DUP (<0, ' ', 0, ' ', 0>)
sysmetrics LABEL BYTE
DB SM_CXSCREEN, "SM_CXSCREEN", 0, "Screen width in pixels", 0
DB SM_CYSCREEN, "SM_CYSCREEN", 0, "Screen height in pixels", 0
DB SM_CXVSCROLL, "SM_CXVSCROLL", 0, "Vertical scroll width", 0
...
But this is a bad decision. I don’t like it.
The LENGTHOF operator counts the number of elements in a single data declaration. Not to be confused with SIZEOF Operator.
Re: “To calculate the number of elements, divide the size in bytes of all the elements (the difference between the two labels) by the size in bytes of one element.”
Thank you. This is a better solution.
.data
sysmet struc
iIndex DB 0
szLabel DB 22 DUP (0)
zero1 DB 0
szDesc DB 40 DUP (0)
zero2 DB 0
sysmet ends
sysm sysmet <SM_CXSCREEN, "SM_CXSCREEN", 0, "Screen width in pixels", 0>,
<SM_CYSCREEN, "SM_CYSCREEN", 0, "Screen height in pixels", 0>,
…
sysmet <SM_CMONITORS, "SM_CMONITORS", 0, "Number of monitors", 0>,
<SM_SAMEDISPLAYFORMAT, "SM_SAMEDISPLAYFORMAT", 0, "Same color format flag", 0>
lenOfSysm = $-sysm
.code
;cLineNumbers = lenOfSysm / sizeof sysmet
xor EDX, EDX
mov EAX, lenOfSysm
mov EBX, sizeof sysmet
div EBX
mov cLineNumbers, EAX
But this is still a bypass of MASM restrictions. Microsoft seems to have stopped properly supporting MASM.
3
You can do the initialization in multiple sysmet lines and put a label after them, then calculate the size from the difference between the end label and the sysm start label.
To calculate the number of elements, divide the size in bytes of all the elements (the difference between the two labels) by the size in bytes of one element.
Eric Postpischil
.data
sysmet struc
iIndex DB 0
szLabel DB 22 DUP (0)
zero1 DB 0
szDesc DB 40 DUP (0)
zero2 DB 0
sysmet ends
sysm sysmet <SM_CXSCREEN, "SM_CXSCREEN", 0, "Screen width in pixels", 0>,
<SM_CYSCREEN, "SM_CYSCREEN", 0, "Screen height in pixels", 0>,
…
sysmet <SM_CMONITORS, "SM_CMONITORS", 0, "Number of monitors", 0>,
<SM_SAMEDISPLAYFORMAT, "SM_SAMEDISPLAYFORMAT", 0, "Same color format flag", 0>
lenOfSysm = $-sysm
.code
;cLineNumbers = lenOfSysm / sizeof sysmet
xor EDX, EDX
mov EAX, lenOfSysm
mov EBX, sizeof sysmet
div EBX
mov cLineNumbers, EAX
1