New packages for UASM 2.41 are up as well as an updated version of WinInc with a number of fixes.
UASM 2.41 updates a number of additional compiler warnings, but most importantly a totally re-worked implementation of RECORD directive and operator.
.data
COLOR RECORD blink:1, back:3, intense:1, fore:3
safir COLOR <1, 2, 0, 4>
COBALT STRUCT
pntr DWORD ?
rc COLOR <>
COBALT ENDS
cobalt COBALT <>
COLOR64 RECORD blink:8, back:8, intense:8, fore:8,blink1:8, back1:8, intense1:8, fore1:8
safir64 COLOR64 <224, 225, 226, 14, 224, 225, 226, 14>
.code
mov cl, COLOR<1, 7, 0, 1>
mov cobalt.rc, COLOR<1, 7, 0, 1>
mov rax,safir64
In addition to RECORDS of 32bits, 64bit RECORDS can be declared in .data and manually referenced OR used inline in code if the destination is a 64bit GPR:
mov rax,COLOR <224, 225, 226, 14, 224, 225, 226, 14> ; E0E1E20EE0E1E20E
mov rcx,COLOR <224, 225, 226, 14, 224, 225, 226, 14> ; E0E1E20EE0E1E20E
Git source updated in 2.41 branch and master.
Cheers
John
You can use 64 bit value direct in 64 bit registers:
mov rax,COLOR <224, 225, 226, 14, 224, 225, 226, 14> ; E0E1E20EE0E1E20E
but that will throw an error:
mov cobalt.rc,COLOR <224, 225, 226, 14, 224, 225, 226, 14> ; E0E1E20EE0E1E20E
and this as well:
mov ecx,COLOR <224, 225, 226, 14, 224, 225, 226, 14> ; E0E1E20EE0E1E20E
this works fine:
mov ecx,COLOR <224, 225, 226, 14> ; E0E1E20E
and this as well:
mov cobalt.rc,COLOR <224, 225, 226, 14> ; E0E1E20E
UASM takes care if incorrect values used in RECORD 8)
this is from jimg source from this forum:
prtf "bear in mind that ML doesn't care if you enter stuff that doesn't match the specs for the record"
;but UASM cares, if you uncomment nex 2 lines it will throw errors
;mov dcbw.fbits,wBITRECORD<9,9,9,9,9,9,9,9,9,9,9,9,9,9>
;prtf "entering 9 for every field gives jibberish, should have cause assembly error - fbits=%x",dcbw.fbits
DCB struct changed in winbase.h to this to be compatible with masm:
BITRECORD RECORD fBinary:1,fParity:1,fOutxCtsFlow:1,fOutxDsrFlow:1,fDtrControl:2,fDsrSensitivity:1,fTXContinueOnXoff:1,fOutX:1,fInX:1,fErrorChar:1,fNull:1,fRtsControl:2,fAbortOnError:1,fDummy2:17
DCB STRUCT
DCBlength DWORD ?
BaudRate DWORD ?
fbits BITRECORD <>
wReserved WORD ?
XonLim WORD ?
XoffLim WORD ?
ByteSize BYTE ?
Parity BYTE ?
StopBits BYTE ?
XonChar BYTE ?
XoffChar BYTE ?
ErrorChar BYTE ?
EofChar BYTE ?
EvtChar BYTE ?
wReserved1 WORD ?
DCB ENDS
LPDCB typedef ptr DCB
I believe that all issues with the SWITCH - ENDSWITCH block have been solved :t
Quote from: habran on September 29, 2017, 11:14:22 PM
DCB struct changed in winbase.h to this to be compatible with masm:
BITRECORD RECORD fBinary:1,fParity:1,fOutxCtsFlow:1,fOutxDsrFlow:1,fDtrControl:2,fDsrSensitivity:1,fTXContinueOnXoff:1,fOutX:1,fInX:1,fErrorChar:1,fNull:1,fRtsControl:2,fAbortOnError:1,fDummy2:17
DCB STRUCT
DCBlength DWORD ?
BaudRate DWORD ?
fbits BITRECORD <>
wReserved WORD ?
XonLim WORD ?
XoffLim WORD ?
ByteSize BYTE ?
Parity BYTE ?
StopBits BYTE ?
XonChar BYTE ?
XoffChar BYTE ?
ErrorChar BYTE ?
EofChar BYTE ?
EvtChar BYTE ?
wReserved1 WORD ?
DCB ENDS
LPDCB typedef ptr DCB
I don't understand this part. The declaration of BITRECORD RECORD is wrong in Windows.inc because records in MASM are in reverse order of records in C.
There is even an old discussion about this here (http://www.masmforum.com/board/index.php?PHPSESSID=8d46cd4ecb1688be429ab49694ec53e6&topic=8507.0;wap2).
This was there before:
DCB_R0 RECORD fDummy2:17,fAbortOnError:1,fRtsControl:2,fNull:1,fErrorChar:1,\
fInX:1,fOutX:1,fTXContinueOnXoff:1,fDsrSensitivity:1,fDtrControl:2,\
fOutxDsrFlow:1,fOutxCtsFlow:1,fParity:1,fBinary:1
DCB struct
DCBlength DWORD ?
BaudRate DWORD ?
r0 DCB_R0 <>
wReserved WORD ?
XonLim WORD ?
XoffLim WORD ?
ByteSize BYTE ?
Parity BYTE ?
StopBits BYTE ?
XonChar SBYTE ?
XoffChar SBYTE ?
ErrorChar SBYTE ?
EofChar SBYTE ?
EvtChar SBYTE ?
wReserved1 WORD ?
DCB ends
LPDCB typedef ptr DCB
Jimg has given this info in his example:
; stock BITRECORD from windows.inc but with w prepended and with binary set so we can find it
wBITRECORD RECORD wBinary:1=1,wParity:1,wOutxCtsFlow:1,wOutxDsrFlow:1,wDtrControl:2,wDsrSensitivity:1,wTXContinueOnXoff:1,wOutX:1,wInX:1,wErrorChar:1,wNull:1,wRtsControl:2,wAbortOnError:1,wDummy2:17
; reversed definition
zBITRECORD RECORD zDummy2:17,zAbortOnError:1,zRtsControl:2,zNull:1,zErrorChar:1,zInX:1,zOutX:1,zTXContinueOnXoff:1,zDsrSensitivity:1,zDtrControl:2,zOutxDsrFlow:1,zOutxCtsFlow:1,zParity:1,zBinary:1=1
so, tell me which one is really reversed, or better yet:
we should finally all agree about it
then we can make as you wish
To me doesn't matter it can not run on my machine and I can not check which one is reverse and which one is not.
Habran,
I am not sure what jimg said in every occasion. What I can quote from Jimg is this:
"I disagree. The final correct result is to define the record properly, not like it is in windows.inc" (http://masm32.com/board/index.php?topic=6557.msg70304#msg70304)
So, the correct definition (subject, of course, to confirmation from Jimg) should be :
BITRECORD RECORD fDummy2:17,fAbortOnError:1,fRtsControl:2, fNull:1,fErrorChar:1,fInX:1,fOutX:1, fTXContinueOnXoff:1,fDsrSensitivity:1,fDtrControl:2,fOutxDsrFlow:1,fOutxCtsFlow:1,fParity:1,fBinary:1
Quote from: johnsa on September 29, 2017, 10:30:05 PM
In addition to RECORDS of 32bits, 64bit RECORDS can be declared in .data and manually
This does not work in 32-bit and does not work as advertised in 64-bit:
includelib \masm32\lib64\msvcrt.lib
OPTION LITERALS:ON
printf proto :ptr, :vararg
_FP32 RECORD sign:1, exponent:8, mantissa:23
FP32_t UNION
parts _FP32 <>
number REAL4 ?
FP32_t ENDS
.data
someFloat FP32_t <>
.code
main proc
LOCAL _real8 : REAL8
; This works ...
mov rcx, _FP32<0, 80h, 4ccccdh> ; but why need a 64-bit register for a 32-bit record?
mov someFloat.parts, ecx
; This does not work:
; mov someFloat.parts, _FP32<0, 80h, 4ccccdh>
fld someFloat.number
fstp _real8
INVOKE printf, "Value %f", _real8 ; expected to print 3.2
ret
main endp
end main
Why are you using \masm32\lib64\msvcrt.lib
I never succeeded to build anything with that
here is your code:
--- awrec.asm ------------------------------------------------------------------
1: includelib msvcrt.lib
2:
3: OPTION LITERALS:ON
4:
5: printf proto :ptr, :vararg
6:
7: _FP32 RECORD sign:1, exponent:8, mantissa:23
8: FP32_t UNION
9: parts _FP32 <>
10: number REAL4 ?
11: FP32_t ENDS
12:
13: .data
14: someFloat FP32_t <>
15:
16: .code
17:
18: main proc
00007FF6E6E71010 55 push rbp
00007FF6E6E71011 48 8B EC mov rbp,rsp
00007FF6E6E71014 48 83 EC 10 sub rsp,10h
19: LOCAL _real8 : REAL8
20: ; This works ...
21: mov ecx, _FP32<0, 80h, 4ccccdh> ; but why need a 64-bit register for a 32-bit record?
22: mov someFloat.parts, ecx
00007FF6E6E71018 89 0D E2 3F 00 00 mov dword ptr [someFloat (07FF6E6E75000h)],ecx
23: ; This does not work:
24: mov someFloat.parts, _FP32<0, 80h, 4ccccdh>
25:
26: fld someFloat.number
00007FF6E6E7101E D9 05 DC 3F 00 00 fld dword ptr [someFloat (07FF6E6E75000h)]
27: fstp _real8
00007FF6E6E71024 DD 5D F8 fstp qword ptr [_real8]
28: INVOKE printf, "Value %f", _real8 ; expected to print 3.2
00007FF6E6E71027 48 83 EC 20 sub rsp,20h
00007FF6E6E7102B 48 8B 55 F8 mov rdx,qword ptr [_real8]
00007FF6E6E7102F 48 8D 0D D7 3F 00 00 lea rcx,[__ls2393 (07FF6E6E7500Dh)]
00007FF6E6E71036 E8 1D 10 00 00 call printf (07FF6E6E72058h)
00007FF6E6E7103B 48 83 C4 20 add rsp,20h
29: ret
00007FF6E6E7103F 48 83 C4 10 add rsp,10h
00007FF6E6E71043 5D pop rbp
00007FF6E6E71044 C3 ret
--- No source file -------------------------------------------------------------
Now I can see that mov ecx, _FP32<0, 80h, 4ccccdh> ; but why need a 64-bit register for a 32-bit record?
is skipped as well as :
mov someFloat.parts, _FP32<0, 80h, 4ccccdh>
It is interesting find :dazzled:
I'll check on it
For 64 bit records:
includelib \masm32\lib64\msvcrt.lib
OPTION LITERALS:ON
printf proto :ptr, :vararg
_FP64 RECORD sign:1, exponent:11, mantissa:52
FP64_t UNION
parts _FP64 <>
number REAL8 ?
FP64_t ENDS
.data
someDouble FP64_t <>
.code
main proc
; This does not assemble the record correctly
mov rax, _FP64<0, 400h, 999999999999Ah>
mov someDouble.parts, rax
; and this does not work at all:
;mov someDouble.parts, _FP64<0, 400h, 999999999999Ah>
INVOKE printf, "Value %f", someDouble.number ; expected to print 3.2
ret
main endp
end main
Quote
Why are you using \masm32\lib64\msvcrt.lib
msvcrt has many enemies here but everybody uses it, even disguised as crt_somefunction. :biggrin:
Quote from: aw27 on September 30, 2017, 07:33:20 PMmsvcrt has many enemies here but everybody uses it, even disguised as crt_somefunction. :biggrin:
Well,
almost everybody ;)
I have found what was wrong, will be fixed soon and I'll post the exe here as soon as I fix it because I don't believe that John will be available tonight (OZ time)
That was very good find aw27 :t
as you know we see what we want to see but it doesn't have to be a common reality :biggrin:
Quote from: jj2007 on September 30, 2017, 07:39:57 PM
Quote from: aw27 on September 30, 2017, 07:33:20 PMmsvcrt has many enemies here but everybody uses it, even disguised as crt_somefunction. :biggrin:
Well, almost everybody ;)
Show me something built by your Basic that does not call msvcrt.dll. :icon_rolleyes:
Quote from: habran on September 30, 2017, 07:46:01 PM
I have found what was wrong, will be fixed soon and I'll post the exe here as soon as I fix it because I don't believe that John will be available tonight (OZ time)
That was very good find aw27 :t
as you know we see what we want to see but it doesn't have to be a common reality :biggrin:
For the 64 bit case, if we have a frame, even if not needed, it will assemble the record correctly: :badgrin:
main proc
LOCAL someVar : dword
mov someVar, 1
; Now assemble the record correctly
mov rax, _FP64<0, 400h, 999999999999Ah>
mov someDouble.parts, rax
; and this does not work:
;mov someDouble.parts, _FP64<0, 400h, 999999999999Ah>
INVOKE printf, "Value %f", someDouble.number ; expected to print 3.2
ret
main endp
now this assembles properly:
--- awrec.asm ------------------------------------------------------------------
1: includelib msvcrt.lib
2:
3: OPTION LITERALS:ON
4:
5: printf proto :ptr, :vararg
6:
7: _FP32 RECORD sign:1, exponent:8, mantissa:23
8: FP32_t UNION
9: parts _FP32 <>
10: number REAL4 ?
11: FP32_t ENDS
12:
13: .data
14: someFloat FP32_t <>
15:
16: .code
17:
18: main proc
00007FF750E61010 55 push rbp
00007FF750E61011 48 8B EC mov rbp,rsp
00007FF750E61014 48 83 EC 10 sub rsp,10h
19: LOCAL _real8 : REAL8
20: ; This works ...
21: mov ecx, _FP32<0, 80h, 4ccccdh> ; but why need a 64-bit register for a 32-bit record?
00007FF750E61018 B9 CD CC 4C 40 mov ecx,404CCCCDh
22: mov someFloat.parts, ecx
00007FF750E6101D 89 0D DD 3F 00 00 mov dword ptr [someFloat (07FF750E65000h)],ecx
23: ; This does not work:
24: mov someFloat.parts, _FP32<0, 80h, 4ccccdh>
00007FF750E61023 C7 05 D3 3F 00 00 CD CC 4C 40 mov dword ptr [someFloat (07FF750E65000h)],404CCCCDh
25:
26: fld someFloat.number
00007FF750E6102D D9 05 CD 3F 00 00 fld dword ptr [someFloat (07FF750E65000h)]
27: fstp _real8
00007FF750E61033 DD 5D F8 fstp qword ptr [_real8]
28: INVOKE printf, "Value %f", _real8 ; expected to print 3.2
00007FF750E61036 48 83 EC 20 sub rsp,20h
00007FF750E6103A 48 8B 55 F8 mov rdx,qword ptr [_real8]
00007FF750E6103E 48 8D 0D C8 3F 00 00 lea rcx,[__ls2393 (07FF750E6500Dh)]
00007FF750E61045 E8 18 10 00 00 call printf (07FF750E62062h)
00007FF750E6104A 48 83 C4 20 add rsp,20h
29: ret
00007FF750E6104E 48 83 C4 10 add rsp,10h
00007FF750E61052 5D pop rbp
00007FF750E61053 C3 ret
--- No source file -------------------------------------------------------------
Interesting enough, that last one
QuoteFor the 64 bit case, if we have a frame, even if not needed, it will assemble the record correctly: :badgrin:
causes uasm to break in :dazzled:
What did you mean with " if we have a frame"?
Can you give me a complete source please of the last one?
deleted
Please explain(Pauline) :biggrin:
aw27, here is fixed uasm.exe for the first part
I don't have enough info for the second part
Quote from: habran on September 30, 2017, 08:33:31 PM
Can you give me a complete source please of the last one?
Sure:
includelib \masm32\lib64\msvcrt.lib
OPTION LITERALS:ON
printf proto :ptr, :vararg
_FP64 RECORD sign:1, exponent:11, mantissa:52
FP64_t UNION
parts _FP64 <>
number REAL8 ?
FP64_t ENDS
.data
someDouble FP64_t <>
.code
main proc
LOCAL someVar : dword
mov someVar, 1
; This assemble the record correctly when there is a frame as we have here now
mov rax, _FP64<0, 400h, 999999999999Ah>
mov someDouble.parts, rax
; and this does not work:
;mov someDouble.parts, _FP64<0, 400h, 999999999999Ah>
INVOKE printf, "Value %f", someDouble.number ; expected to print 3.2
ret
main endp
end main
Let me know what is wrong here:
sorry, I was watching a movie (Witness, with Harrison Ford) with one eye
I can see what is wrong now
--- awrec.asm ------------------------------------------------------------------
1:
2: includelib msvcrt.lib
3:
4: OPTION LITERALS:ON
5:
6: printf proto :ptr, :vararg
7:
8: _FP64 RECORD sign:1, exponent:11, mantissa:52
9: FP64_t UNION
10: parts _FP64 <>
11: number REAL8 ?
12: FP64_t ENDS
13:
14: .data
15: someDouble FP64_t <>
16:
17: .code
18:
19: main proc
00007FF6FB5F1010 55 push rbp
00007FF6FB5F1011 48 8B EC mov rbp,rsp
00007FF6FB5F1014 48 83 EC 10 sub rsp,10h
20: LOCAL someVar : dword
21: mov someVar, 1
00007FF6FB5F1018 C7 45 FC 01 00 00 00 mov dword ptr [someVar],1
22: ; This assemble the record correctly when there is a frame as we have here now
23: mov rax, _FP64<0, 400h, 999999999999Ah>
00007FF6FB5F101F 48 B8 9A 99 99 99 99 99 09 40 mov rax,400999999999999Ah
24: mov someDouble.parts, rax
00007FF6FB5F1029 48 89 05 D0 3F 00 00 mov qword ptr [someDouble (07FF6FB5F5000h)],rax
25: ; and this does not work:
26: ;mov someDouble.parts, _FP64<0, 400h, 999999999999Ah>
27:
28: INVOKE printf, "Value %f", someDouble.number ; expected to print 3.2
00007FF6FB5F1030 48 83 EC 20 sub rsp,20h
00007FF6FB5F1034 48 8B 15 C5 3F 00 00 mov rdx,qword ptr [someDouble (07FF6FB5F5000h)]
00007FF6FB5F103B 48 8D 0D D8 3F 00 00 lea rcx,[__ls2393 (07FF6FB5F501Ah)]
00007FF6FB5F1042 E8 19 10 00 00 call printf (07FF6FB5F2060h)
00007FF6FB5F1047 48 83 C4 20 add rsp,20h
29: ret
00007FF6FB5F104B 48 83 C4 10 add rsp,10h
00007FF6FB5F104F 5D pop rbp
00007FF6FB5F1050 C3 ret
--- No source file -------------------------------------------------------------
That is actually not wrong:
1>awrec.asm(26): error A2055: Initializer value too large
because only GPR 64 bit registers can accept 64 bit constant unfortunately, you should complain to INTEL ;)
So, uasm is not letting you get wrong data
It took me several hours to actually make that happen, here is the code from expreval.c:
if (recordsym && recordsym->sym.typekind == TYPE_RECORD)
{
if ( InitRecordVar( opnd1, curr_operator, tokenarray, recordsym, NULL ) != ERROR )
if (tokenarray[1].token == T_REG) {
p=tokenarray->tokpos + 3;
while (isspace(*p))p++;
if (*p == 'r' || *p == 'R')
rc = NOT_ERROR;
else goto testsize;
}else
testsize: if (opnd1->llvalue < 0x100000000){
rc = NOT_ERROR;
}
else {
rc = ERROR;
EmitErr(INITIALIZER_OUT_OF_RANGE);
}
return( rc );
}
else
OperErr( curr_operator, tokenarray );
}
break;
that is what would happen if I let it happen:
26: mov someDouble.parts, _FP64<0, 400h, 999999999999Ah>
00007FF6A40E1030 48 C7 05 C5 3F 00 00 9A 99 99 99 mov qword ptr [someDouble (07FF6A40E5000h)],0FFFFFFFF9999999Ah
INTEL extends 32 bit to this: 0FFFFFFFF9999999Ah instead of 400999999999999Ah
that happens with all instructions except MOV GPR64,64BITVALUE
not even CMP RAX, 400999999999999Ah would work, so you have to do this:
MOV RCX,400999999999999Ah
CMP RAX,RCX
but I am sure you are aware of that
so that uasm64.exe above is now wrking as it is supposed to 8)
Quote from: habran on September 30, 2017, 11:59:45 PM
1>awrec.asm(26): error A2055: Initializer value too large
because only GPR 64 bit registers can accept 64 bit constant unfortunately, you should complain to INTEL ;)
So, uasm is not letting you get wrong data
Damn, I was expecting some behind the scene magic from UAsm to make it happen. :(
We could have done that magic behind the scene but it would be more appropriate to do it with a sleight of hand what you have done already :lol::
23: mov rax, _FP64<0, 400h, 999999999999Ah>
00007FF66074101F 48 B8 9A 99 99 99 99 99 09 40 mov rax,400999999999999Ah
24: mov someDouble.parts, rax
00007FF660741029 48 89 05 D0 3F 00 00 mov qword ptr [someDouble (07FF660745000h)],rax
because this is exactly what we would have to do behind the scene ;)
IMAO that sleight of hand is already more than any other assembler can do 8)
IYAO, is the presence of a frame necessary to make mov rax, _FP64<0, 400h, 999999999999Ah> work then? Or you just forgot that detail?
which frame? :dazzled:
Try that uasm64.exe above and see if works as you expect, if not give me wrong code.
Quote from: habran on October 01, 2017, 12:03:50 PM
which frame? :dazzled:
Try that uasm64.exe above and see if works as you expect, if not give me wrong code.
You can't really see the differences in spite of my supply of complete examples. :(
Let me try again:
1)
; This does not assemble the record correctly <-------------
mov rax, _FP64<0, 400h, 999999999999Ah>
What I meant is that the value that goes to rax is not correct.
2)
LOCAL someVar : dword
mov someVar, 1
mov rax, _FP64<0, 400h, 999999999999Ah>
Here the value that goes into rax is correct. The existence of a frame, i.e, LOCAL someVar:dword, made a difference in spite of being apparently irrelevant for the case.
I've been reading this thread. My bitrecord test runs now. I still think it's defined wrong in windows.inc, but this test
.code
program:
xBITRECORD RECORD xBinary:1, xParity:1, xOutxCtsFlow:1, xOutxDsrFlow:1, xDtrControl:2,
xDsrSensitivity:1, xTXContinueOnXoff:1, xOutX:1,xInX:1, xErrorChar:1, xNull:1,
xRtsControl:2, xAbortOnError:1, xDummy2:17
mov dcbx.fbits, xBITRECORD < TRUE, NULL, TRUE, TRUE, DTR_CONTROL_HANDSHAKE, FALSE, \
FALSE, FALSE, FALSE, FALSE, FALSE, RTS_CONTROL_HANDSHAKE, FALSE, NULL >
;used to give : Error A2151: Missing operator in expression
ret
end program
no longer gives the error comment.
However, I now get the following error in a rather large program I am currently working on. I haven't isolated it yet, but when I do, I will post some code-
UASM v2.41, Sep 29 2017, Masm-compatible assembler.
Portions Copyright (c) 1992-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.
***********
ASCII build
***********
F:\masm32\INCLUDE\winextra.inc(25183) : Error A2169: General Failure
F:\masm32\INCLUDE\winextra.inc(25183): Included by
F:\masm32\INCLUDE\windows.inc(26889): Included by
F:\WinAsm\Progs\Sol\Sol.asm(169): Main line code
the pertinent section of the output file looks like this-
markblk macro sectionname
> tsiz = $ - markblockprevious
> ctotmem=ctotmem+tsiz
> markblockprevious = $
> markblockname catstr markblockname,<," >,markblocksavename,<=>,%tsiz,<">
> markblocksavename textequ <sectionname>
> endm
markblk stdlibs
= 0 1 tsiz = $ - markblockprevious
= 0 1 ctotmem=ctotmem+tsiz
00000000 = 0 1 markblockprevious = $
= ," =0" 1 markblockname catstr <>,<," >,<>,<=>,<0>,<">
= stdlibs 1 markblocksavename textequ <stdlibs>
Error A2169: General Failure
I'm working on getting a cleaner example of the problem. Version 40 works without error.
Scratch that. The error is occurring somewhere in the "include windows.inc" , which was the next line after the markblk macro.
I'll run it down and let you know what the conflict was.
I stripped the program down to this-
.686p
.model flat, stdcall
option casemap :none ; case sensitive
.xmm
.data
ProgName db "Uasm Test",0
.code
.nolist
include windows.inc
.code
Program:
invoke ExitProcess, 0
end Program
and get
UASM v2.41, Sep 29 2017, Masm-compatible assembler.
Portions Copyright (c) 1992-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.
***********
ASCII build
***********
F:\masm32\INCLUDE\winextra.inc(25183) : Error A2169: General Failure
F:\masm32\INCLUDE\winextra.inc(25183): Included by
F:\masm32\INCLUDE\windows.inc(26889): Included by
R:\bugtest\Sol.asm(10): Main line code
If I take out the .nolist, I get
F:\masm32\INCLUDE\windows.inc(21253) : Error A2169: General Failure
F:\masm32\INCLUDE\windows.inc(21253): Included by
R:\bugtest\Sol.asm(10): Main line code
So I really don't know how to pin down the error much more without stripping stuff out of windows.inc
p.s.
I just downloaded and installed the latest masm32v11r.zip to get windows.inc and winextra.inc to be sure mine weren't corrupted. They were identical, so that's not the problem.
Thanks Jimg :t
I tried to build your example few days ago with masm32 windows.inc and didn't succeed
So, I tried WinInc and it was having a problem with DCB struct, so I changed it in winuser.inc to one from masm32 windows.inc and it was working fluently.
I was using this on the top:
.486
.MODEL FLAT, stdcall
option casemap:none
pushcontext listing ;suppress listing of includes
.nolist
WIN32_LEAN_AND_MEAN equ 1 ;this is to reduce assembly time
include windows.inc
include Winbase.inc
include winuser.inc
include Commctrl.inc
include wingdi.inc
.list
includelib kernel32.lib
includelib user32.lib
includelib comctl32.lib
includelib gdi32.lib
I don't know what is going on with masm32 but lately I never succeeded to build anything neither 32 nor 64 bit, so I've gave up trying :(
So, do you agree with aw27 about the above issue, let as know which version you want please.
aw27, I have done "the magic behind the scene" but still investigating why it works only with LOCALS without FRAME, !@#$%^&&^%$# :icon_confused:
here is example:
--- awrec.asm ------------------------------------------------------------------
1: ; option casemap:none
2: ; option frame:auto ;generate SEH-compatible prologues and epilogues
3: ;option win64:11 ;reserve stack space once per procedure
4:
5: includelib msvcrt.lib
6:
7: OPTION LITERALS:ON
8:
9: printf proto :ptr, :vararg
10:
11: _FP64 RECORD sign:1, exponent:11, mantissa:52
12: _FP32 RECORD sign1:1, exponent1:7, mantissa1:24
13: FP64_t UNION
14: parts _FP64 <>
15: number REAL8 ?
16: FP64_t ENDS
17: FP32_t UNION
18: parts _FP32 <>
19: number REAL8 ?
20: FP32_t ENDS
21: .data
22: someDouble FP64_t <>
23: double32 FP32_t <>
24: .code
25:
26: main proc ;FRAME USES rbx
00007FF65C8A1010 55 push rbp
00007FF65C8A1011 48 8B EC mov rbp,rsp
00007FF65C8A1014 48 83 EC 10 sub rsp,10h
27: LOCAL someVar : dword
28: mov someVar, 1
00007FF65C8A1018 C7 45 FC 01 00 00 00 mov dword ptr [someVar],1
29: ; This assemble the record correctly when there is a frame as we have here now
30: mov ecx, _FP32<0,30h,99999Ah>
00007FF65C8A101F B9 9A 99 99 30 mov ecx,3099999Ah
31: mov double32.parts,_FP32<0,30h,99999Ah>
00007FF65C8A1024 C7 05 DA 3F 00 00 9A 99 99 30 mov dword ptr [double32 (07FF65C8A5008h)],3099999Ah
32: mov rcx, _FP64<0, 400h, 999999999999Ah>
00007FF65C8A102E 48 B9 9A 99 99 99 99 99 09 40 mov rcx,400999999999999Ah
33: mov someDouble.parts, rcx
00007FF65C8A1038 48 89 0D C1 3F 00 00 mov qword ptr [someDouble (07FF65C8A5000h)],rcx
34: mov someDouble.parts, _FP64<0, 400h, 999999999999Ah> ;Here is that magic behind the scene
00007FF65C8A103F 48 B8 9A 99 99 99 99 99 09 40 mov rax,400999999999999Ah
35: INVOKE printf, "Value %f", someDouble.number ; expected to print 3.2
00007FF65C8A1049 48 89 05 B0 3F 00 00 mov qword ptr [someDouble (07FF65C8A5000h)],rax
00007FF65C8A1050 48 83 EC 20 sub rsp,20h
00007FF65C8A1054 48 8B 15 A5 3F 00 00 mov rdx,qword ptr [someDouble (07FF65C8A5000h)]
00007FF65C8A105B 48 8D 0D C0 3F 00 00 lea rcx,[__ls2393 (07FF65C8A5022h)]
00007FF65C8A1062 E8 21 10 00 00 call printf (07FF65C8A2088h)
00007FF65C8A1067 48 83 C4 20 add rsp,20h
36: ;mov rax, _FP64<0, 400h, 999999999999Ah>
37: ;mov someDouble.parts, rax
38: ;mov someDouble.parts, _FP64<0, 400h, 999999999999Ah>
39: ;vmovq someDouble.parts,xmm0
40: ;and this does not work:
41: ;mov someDouble.parts, _FP64<0, 400h, 999999999999Ah>
42:
43: ret
00007FF65C8A106B 48 83 C4 10 add rsp,10h
00007FF65C8A106F 5D pop rbp
00007FF65C8A1070 C3 ret
--- No source file -------------------------------------------------------------
The listing is a bit off but code is correct
we will have to look at that listing sooner or later :(
Actually, now everything builds fine with frame, without frame, with or without locals, the only problem is with that magic behind the scene ::)
However, that makes it easier to fix
deleted
Quote from: habran on October 01, 2017, 08:17:30 PM
Actually, now everything builds fine with frame, without frame, with or without locals,
:badgrin: :badgrin:
Without frame it prints ZERO, my friend.
I think I have nail it now:
here is your test source with some additional lines, please test it which ever way you can think of
use the new uasm64.exe attached:
; option casemap:none
; option frame:auto ;generate SEH-compatible prologues and epilogues
; option win64:11 ;reserve stack space once per procedure
includelib msvcrt.lib
OPTION LITERALS:ON
printf proto :ptr, :vararg
_FP64 RECORD sign:1, exponent:11, mantissa:52
_FP32 RECORD sign1:1, exponent1:7, mantissa1:24
FP64_t UNION
parts _FP64 <>
number REAL8 ?
FP64_t ENDS
FP32_t UNION
parts _FP32 <>
number REAL8 ?
FP32_t ENDS
.data
someDouble FP64_t <>
double32 FP32_t <>
.code
main proc ;FRAME
;LOCAL someVar : dword
;mov someVar, 1
mov ecx, _FP32<0,30h,99999Ah>
mov double32.parts,_FP32<0,30h,99999Ah>
mov rcx, _FP64<0, 400h, 999999999999Ah>
mov someDouble.parts, rcx
mov someDouble.parts, _FP64<0, 400h, 999999999999Ah>
INVOKE printf, "Value %f", someDouble.number ; expected to print 3.2
mov rax, _FP64<0, 400h, 999999999999Ah>
mov someDouble.parts, rax
mov someDouble.parts, _FP64<0, 400h, 999999999999Ah>
vmovq someDouble.parts,xmm0
;and this now works:
mov someDouble.parts, _FP64<0, 400h, 999999999999Ah>
ret
main endp
end main
Quote
here is your test source with some additional lines
Quote
This is not my test source! It is a confusing salad.
Anyway, you fixed the issues according to this test suit: :t
includelib \masm32\lib64\msvcrt.lib
OPTION LITERALS:ON
printf proto :ptr, :vararg
_FP64 RECORD sign:1, exponent:11, mantissa:52
_FP32 RECORD sign1:1, exponent1:8, mantissa1:23
FP64_t UNION
parts _FP64 <>
number REAL8 ?
FP64_t ENDS
FP32_t UNION
parts _FP32 <>
number REAL4 ?
FP32_t ENDS
.data
someDouble1 FP64_t <>
someDouble2 FP64_t <>
float FP32_t <>
.code
test1 proc
LOCAL _real8 : REAL8
mov ecx, _FP32<0, 80h,4ccccdh>
mov float.parts,ecx
fld float.number
fstp _real8
INVOKE printf, "\nValue %f", _real8 ; expected to print 3.2
ret
test1 endp
test2 proc
mov rcx, _FP64<0, 400h, 999999999999Ah>
mov someDouble1.parts, rcx
INVOKE printf, "\nValue %f", someDouble1.number ; expected to print 3.2
ret
test2 endp
test3 proc
mov someDouble2.parts, _FP64<0, 400h, 999999999999Ah>
INVOKE printf, "\nValue %f", someDouble2.number ; expected to print 3.2
ret
test3 endp
main proc
INVOKE printf, "Tests will pass if value is 3.2, otherwise fail\n"
INVOKE test1
INVOKE test2
INVOKE test3
ret
main endp
end main
But, 64-bit records are NOT supported by UASM in 32-bit assembling. You did not mention that anywhere. In C they are supported in 32-bit as well
That is something wrong with John's .cmd for building with DDK
here is uasm32.exe a debug version built with MSVS 2013 Community
After some rethinking about what you said I am not sure what did you mean, however, if you mean 32 bit assembly programming with 64 bit records, I couldn't care less :badgrin:
Quote from: habran on October 02, 2017, 12:24:34 AM
After some rethinking about what you said I am not sure what did you mean, however, if you mean 32 bit assembly programming with 64 bit records, I couldn't care less :badgrin:
I would care, 32-bit will be here for next 20 years, at least. :shock:
Quote from: habran on October 01, 2017, 07:47:05 PM
Thanks Jimg :t
I tried to build your example few days ago with masm32 windows.inc and didn't succeed
So, I tried WinInc and it was having a problem with DCB struct, so I changed it in winuser.inc to one from masm32 windows.inc and it was working fluently.
I was using this on the top:
.486
.MODEL FLAT, stdcall
option casemap:none
pushcontext listing ;suppress listing of includes
.nolist
WIN32_LEAN_AND_MEAN equ 1 ;this is to reduce assembly time
include windows.inc
include Winbase.inc
include winuser.inc
include Commctrl.inc
include wingdi.inc
.list
includelib kernel32.lib
includelib user32.lib
includelib comctl32.lib
includelib gdi32.lib
I don't know what is going on with masm32 but lately I never succeeded to build anything neither 32 nor 64 bit, so I've gave up trying :(
So, do you agree with aw27 about the above issue, let as know which version you want please.
You guys have me confused at this point, but all my test regarding bitrecord now work properly. It is masm that has the bug.
I'm more concerned about the above general failure problem, would you like me to start a new thread for it?
Jimg, it would be great if we start a new thread :t
The issue with the record as Habran discovered seems to be coming from the use of the DDK C compiler, being 12 years old I'd really like to get away from it now.
I've made a test-build for x64 using VS 2017, if it works as well and as fast as previous DDK versions (and we know it fixes the record issue and has better C99 compliance) then I will move forward using that for Windows builds.
If you'd like to test it out:
www.terraspace.co.uk/uasm64_vs17.zip (http://www.terraspace.co.uk/uasm64_vs17.zip)
PS, JimG I tried your sample code using both WinInc and windows.inc from masm32 package and wasn't able to re-produce the general failure.
Quote from: johnsa on October 02, 2017, 08:28:50 AMIf you'd like to test it out
Works perfect with my big sources and is even a tick faster :t
That is a good news JJ, thank you for testing :t
aw27, I have already succeeded to make 32 bit work with 64 bit RECORDS, now I am trying to conjure inline stuff ::)
Quote from: habran on October 02, 2017, 11:41:58 AM
aw27, I have already succeeded to make 32 bit work with 64 bit RECORDS, now I am trying to conjure inline stuff ::)
What is inline staff? It appears that was something you did yesterday, i.e, mov someDouble2.parts, _FP64<0, 400h, 999999999999Ah>
Yes :biggrin:
44: movq cobalt.rc,COLOR<224, 225, 226, 227, 228, 229, 230, 231>
00CC1035 68 E3 E2 E1 E0 push 0E0E1E2E3h
00CC103A 68 E7 E6 E5 E4 push 0E4E5E6E7h
00CC103F F3 0F 7E 2C 24 movq xmm5,mmword ptr [esp]
00CC1044 83 C4 08 add esp,8
00CC1047 66 0F D6 2D 19 50 CC 00 movq mmword ptr ds:[0CC5019h],xmm5
It already works all but I have unwanted additional : movq mmword ptr ds:[385019h],xmm5
it doesnt do any damage but it shouldn't do it at the beginning and at the end:
45: movq cobalt.rc,COLOR<224, 225, 226, 227, 228, 229, 230, 231>
0038102D 66 0F D6 2D 19 50 38 00 movq mmword ptr ds:[385019h],xmm5
00381035 68 E3 E2 E1 E0 push 0E0E1E2E3h
0038103A 68 E7 E6 E5 E4 push 0E4E5E6E7h
0038103F F3 0F 7E 2C 24 movq xmm5,mmword ptr [esp]
00381044 83 C4 08 add esp,8
00381047 66 0F D6 2D 19 50 38 00 movq mmword ptr ds:[385019h],xmm5
I've got a proper data:
XMM5 = 0000000000000000E0E1E2E3E4E5E6E7
cobalt.rc = 0x00385019 e7 e6 e5 e4 e3 e2 e1 e0
but I can not find the reason why is movq mmword ptr ds:[385019h],xmm5 getting executed twice
:dazzled:
I know that it is something trivial but my brains are overheated at the moment ::)
habran,
I have no idea what you are talking about. I don't know where you found those xmm instructions.
In 32-bit:
mov float.parts,_FP32<0, 80h,4ccccdh> is assembled as:
mov dword ptr [rec32c+0x3000 (00403000)],404CCCCDh
In 64-bit:
mov float.parts,_FP32<0, 80h,4ccccdh> is assembled as
mov dword ptr [rec64c+0x3018 (00000001`40003018)],404CCCCDh
mov someDouble2.parts, _FP64<0, 400h, 999999999999Ah> is assembled as
00000001`4000111f 48b89a99999999990940 mov rax,400999999999999Ah
00000001`40001129 488905d81e0000 mov qword ptr [rec64c+0x3008 (00000001`40003008)],rax
Quote
aw27, I have already succeeded to make 32 bit work with 64 bit RECORDS,
I don't think so, it still fails in my test suite. :(
Hi,
We've changed the way this is working to make it more useful .. inline RECORDs will be evaluate before pre-processing of source lines, which means the result of the record can be used anywhere an immediate would be valid IE as an input to a macro or invoke etc.
Neither 32bit nor 64bit code would allow a 64bit immediate to memory move, so we have added MOV64 as a macro to the macrolibrary which is used in cases where you want to inline a direct record directive to memory.
COLOR RECORD blink:8, back:8, intense:8, fore:8,blink1:8, back1:8, intense1:8, fore1:8
COL8 RECORD blinkx:4, backx:4
COL32 RECORD _a:8,_b:8,_c:8,_d:8
COBALT STRUCT
pntr1 DWORD ?
pntr2 DWORD ?
rc COLOR <>
COBALT ENDS
cobalt COBALT <>
safir COLOR <224, 225, 226, 227, 228, 229, 230, 231> ; E0E1E20EE0E1E20E
blue COL8 <1,2>
red COL32 <10,20,30,40>
.CODE
MOV64 cobalt.rc,0x12345678abcdef01
MOV64 cobalt.rc,COLOR<224, 225, 226, 227, 228, 229, 230, 231>
mov al,COL8<2,3>
mov blue,COL8<3,4>
mov red,COL32<0xff,0x01,0x02,0x03>
The MOV64 macro can be used for general purposes as well as shown in the first line.
This method now removes the need for stack/xmm/reg usage as the immediate values are written directly to memory locations.
The implementation of MOV64 is:
MOV64 macro dst:REQ, imm:REQ
mov dword ptr dst, LOW32(imm)
mov dword ptr dst + 4, HIGH32(imm)
ENDM
which keeps it cleaner and also helps to separate out the fact that there is no REAL instruction that moves a 64bit immediate to memory.
Updated download for testing is at :
www.terraspace.co.uk/uasm64_vs17.zip (http://www.terraspace.co.uk/uasm64_vs17.zip)
Cheers
John
MOV64 does not appear to work yet for 64-bit assembling. For 32-bit assembly it works.
Strange way to do it in 64 bit. Using a register is a lot cleaner.
mov rax, 123456789012
mov pmem, rax
I debated it, we had it that way previously for 64bit, but I'm trying to avoid (as far as possible) adding any more things into uasm that do "behind the scenes" manipulation of registers.. between prologue/epilogue/switch and so forth pretty soon you won't know what registers are in what state without looking in a debugger.. so opted for "save the registers"(tm) over speed in this case :)
John,
As long as your pre-processor engine works OK,
i2m MACRO mem,imm
mov rax, imm
mov mem, rax
ENDM
All issues fixed :t :biggrin:
New packages up on the site and committed to git branch 2.41.
Dated 03-10-2017.
Cheers
John
No problems found with my bigger sources :t
:t
The new build of version 2.41 does not run on Windows XP 32-bit and 64-bit :
uasm32.exe is not a valid Win32 application.
uasm64.exe is not a valid Win32 application.
Quote from: Vortex on October 04, 2017, 04:27:36 AM
The new build of version 2.41 does not run on Windows XP 32-bit and 64-bit :
uasm32.exe is not a valid Win32 application.
uasm64.exe is not a valid Win32 application.
Instant hackfix: With Hexview change at offsets 150h and 158h values from 6 to 5. :biggrin:
This must be a by-product of the build running through VS2017, I will investigate.
Edit: So it appears I could compile using a legacy 140 toolset for XP, I'm not sure how that will impact other things however. I will try it and we can test it out separately, if it works I think I'd rather include then a separate download package for pre Vista. Probably make that one just x86 ?
Hi johnsa,
Many thanks to you and habran for your very nice work. A separate package for pre Vista targetting x86 is OK. This x86 release can assemble 64-bit source code with the -win64 option.
Hello,
Thanks aw27, it's the MajorOperatingSystemVersion member of the IMAGE_OPTIONAL_HEADER32 structure set to 6 by the VS 2017 compiler. Replacing 6 with 5 is solving the problem.
IMAGE_OPTIONAL_HEADER32 STRUCT
.
.
.
MajorOperatingSystemVersion WORD ?
fc uasm64.exe uasm64b.exe
Comparing files uasm64.exe and UASM64B.EXE
00000150: 06 05
00000158: 06 05
fc uasm32.exe uasm32b.exe
Comparing files uasm32.exe and UASM32B.EXE
00000140: 06 05
00000148: 06 05
Thanks to Timo for his TLPEView tool analyzing also 64-bit PE files. (http://masm32.com/board/index.php?topic=6498.0)
uasm64b.exe and uasm32b.exe are the patched versions.
johnsa, the solution proposed by aw27 looks OK.
Alright great to hear it :)
I will make a build for pre Vista anyway for us to test and if it works too I'll add it to the packages. I had to just install legacy c++ support for XP first for VS and will do it in the morning.
Cheers
John
Hi,
Please try this version:
www.terraspace.co.uk/uasm32_xp.zip (http://www.terraspace.co.uk/uasm32_xp.zip)
Built using VC toolset 141(XP) for x86.
Quote from: johnsa on October 04, 2017, 08:11:09 PM
Hi,
Please try this version:
www.terraspace.co.uk/uasm32_xp.zip (http://www.terraspace.co.uk/uasm32_xp.zip)
Built using VC toolset 141(XP) for x86.
It works in xp and above.
I don't see any reason for not simply building with the 141_XP toolset, for both 32-bit and 64-bit. :icon_rolleyes:
Quote from: Vortex on October 04, 2017, 04:27:36 AM
The new build of version 2.41 does not run on Windows XP 32-bit and 64-bit :
I thought I was the only person in the Universe with a copy of XP-64 bit. :bgrin:
It's probably a very small universe these days for XP users!
Windows 7 is still my favourite of the bunch, I totally skipped 8 and 8.1 and now have Windows 10.. which has had some annoyances, but overall it's been ok.
I will do that then for 2.42 assuming it doesn't cause any other issues or degrade performance on > XP systems.
https://blogs.msdn.microsoft.com/vcblog/2012/10/08/windows-xp-targeting-with-c-in-visual-studio-2012/ (https://blogs.msdn.microsoft.com/vcblog/2012/10/08/windows-xp-targeting-with-c-in-visual-studio-2012/)
It doesn't look like it should cause any issues with any aspect of the UASM codebase, no DirectX or HLSL etc.
Quote from: johnsa on October 04, 2017, 10:49:29 PM
and now have Windows 10.. which has had some annoyances, but overall it's been ok.
I also prefer 7 to 10. Things require more clicks to get done with every new version of Windows, the same essential things are the same since Windows NT, but are hidden behind layers and layers of obfuscation crap as if Microsoft was ashamed of them. :icon_rolleyes:
Hi johnsa,
Thanks, uasm32_xp.exe works fine on my Windows XP 64-bit system.