Hi,
UASM cannot determine the type of variables on all possible variations, for example
and al,NOT(SET)
and [ebx].COBii[USER.Look],(1 shl GR) or (1 shl GR)
or [ebx].COBii[USER.J],eax
Multiple error messages look like this>
Error A2048: Operands must be the same size: 4 - 8
Error A2048: Operands must be the same size: 1 - 2
Error A2071: Invalid operand size for instruction
Then I have to rewrite the code>
and al,NOT byte PTR (SET)
or dword ptr [ebx].COBii[USER.J],eax
JWASM documentation writes - https://wiki.osdev.org/JWasm
Quote
Abbreviated Notation
This notation is a fully specified format which occurs in the following form:
mov eax, DWORD PTR [edi]
Over time, the parsers in assemblers have improved to the stage where if the assembler can recognize the size of the data then the SIZE specifier may be omitted as such.
mov eax, [edi]
This allows for clearer code that is easier to read. However, there are some contexts where the assembler cannot independently determine the data size; For example, if the source operand is a memory operand. In this situation the historical data SIZE specifiers must be used. The following is an example of this situation.
movzx eax, [esi] ; generates an error - data SIZE cannot be determined by the assembler
movzx eax, BYTE PTR [esi] ; zero extend a BYTE into the 32 bit EAX register
The same code is well understood by the original macro assembler. In which you do not need to add anything, I consider it as violation in compatibility.
In addition, there is another error with UASM: fatal error LNK1107: invalid or corrupt file: cannot read at 0x15AB
mainMasm.asm(78) : Error A2048: Operands must be the same size: 1 - 2
mainMasm.asm(79) : Error A2071: Invalid operand size for instruction
mainMasm.asm(80) : Error A2048: Operands must be the same size: 8 - 4
mainMasm.asm: 101 lines, 1 passes, 1 ms, 0 warnings, 3 errors
Microsoft (R) Incremental Linker Version 14.29.30037.0
Copyright (C) Microsoft Corporation. All rights reserved.
Because of these errors, I can't assemble a large project :biggrin:, editing the entire code can't be a solution either :skrewy:, Microsoft assembler works without errors :badgrin:
mov ebx, offset COA
; assume ebx:PTR _COA avoid this syntax, no good for readability
Obi equ [ebx._COA.COBii] ; much better
and al, NOT(GET) ; NO fatal error LNK1107 here with polink - which linker do you use?
int 3 ; have a look...
and al, NOT(SET) ; -205... does it really fit into a byte? MASM thinks it does, UAsm disagrees
and ax, NOT(SET) ; works for UAsm and MASM
and eax, NOT(SET) ; works for UAsm and MASM
and [ebx._COA.COBii.Look], (1 shl GR) or (1 shl GR)
or [ebx._COA.COBii.J],eax
or Obi.J, eax ; isn't that cute?
Quote from: LiaoMi on June 07, 2022, 05:05:32 AM movzx eax, [esi] ; generates an error - data SIZE cannot be determined by the assembler
movzx eax, BYTE PTR [esi] ; zero extend a BYTE into the 32 bit EAX register
The same code is well understood by the original macro assembler. In which you do not need to add anything, I consider it as violation in compatibility.
What exactly do you mean? MASM allows movzx eax, [esi]???
Hi jj2007,
I meant just my attached example, without taking into account the quote from the documentation.
An example is below:
mainMasm.obj : fatal error LNK1107: invalid or corrupt file: cannot read at 0x15C5
Microsoft (R) Incremental Linker Version 14.29.30037.0
1 byte is 255, SET equ 11001100B - > 204 - > NOT 204 - > 51
Where does the negative number come from?
polink doesn't like your object file...
\Masm32\Members\LiaoMi\UasmBug>\Masm32\bin\polink /SubSystem:console /machine:x86 mainMasm.obj
POLINK: fatal error: Invalid machine type in object 'mainMasm.obj'.
Quote from: LiaoMi on June 07, 2022, 07:43:49 AM
1 byte is 255, SET equ 11001100B - > 204 - > NOT 204 - > 51
Where does the negative number come from?
32- or 64-bit arithmetic and logic
NOT CCh --> FFFFFF33h --> -205, which is less than -128
Hi jj2007,
the difference is in the three lines that are commented out, assembly was done using UASM:
Quoteand al,NOT(GET) ; < BUG - fatal error LNK1107: invalid or corrupt file: cannot read at 0x15AB
;and al,NOT(SET)
;and [ebx].COBii[USER.Look],(1 shl GR) or (1 shl GR)
;or [ebx].COBii[USER.J],eax
I couldn't find any additional information on how it should be correct ... operator NOT - https://docs.microsoft.com/en-us/cpp/assembler/masm/operator-not?view=msvc-170. In the new example, the object file also turns out to be broken. :rolleyes:
or Obi.J, eax ; isn't that cute?
:biggrin: Yes, it looks cute! I've never seen this type of writing before. I also liked your user archive :thumbsup: :biggrin: \Masm32\Members\LiaoMi\
Quote from: tenkey on June 07, 2022, 03:59:02 PM
Quote from: LiaoMi on June 07, 2022, 07:43:49 AM
1 byte is 255, SET equ 11001100B - > 204 - > NOT 204 - > 51
Where does the negative number come from?
32- or 64-bit arithmetic and logic
NOT CCh --> FFFFFF33h --> -205, which is less than -128
:thumbsup: My calculator showed the wrong thing, but everything is fine in the Windows calculator :biggrin: Thanks!
Quote from: LiaoMi on June 08, 2022, 01:50:05 AMor Obi.J, eax ; isn't that cute?
:biggrin: Yes, it looks cute! I've never seen this type of writing before.
The equate Obi equ [ebx._COA.COBii] can be changed any time, in case you want to use edi, for example: Obi equ [
edi._COA.COBii].
I try to stick to one index register, in order to avoid confusion.
Re NOT: I don't think there is a scientifically correct answer. It's a matter of interpretation. Masm sees a BYTE, the Watcom assemblers see 32-bit arithmetic. Avoid this kind of acrobatics...
Quote from: jj2007 on June 08, 2022, 02:30:52 AM
Re NOT: I don't think there is a scientifically correct answer. It's a matter of interpretation. Masm sees a BYTE, the Watcom assemblers see 32-bit arithmetic. Avoid this kind of acrobatics...
"First, the macro doesn't compute anything. It is substituted into a source code, expanded, and the resulting text gets compiled. What the resulting text is, depends on the way you use the macro, especially on what parameter you give."
"For a negative decimal number, the MACRO must form its absolute value as a positive number."
GETa equ -88
GETb equ (-88)
GETc equ 88
GETd equ -88t
mov al, GETa
mov al, GETb
mov al, GETc
mov al, GETd
mov al, 0A8h
mov al, 0A8h
mov al, 58h ; 'X'
mov al, 0A8h
/* A public EQU can be negative, so must adjust value */
/* this brain damage is happening because masm keeps numbers
* in 17/33 bit sign magnitude representation */
if ((pglob->symkind == EQU) && pglob->symu.equ.equrec.expr.esign)
pubvalue = (short)(((use32==0x91? 0xffffffffl : 65535) - pglob->offset) + 1);
But macros must treat values as absolute, otherwise it contradicts the code itself, which uses the byte register. Therefore, I believe that the processing in MASM from Microsoft is logically correct.
In another case:
"H2INC places an OPTION EXPR32 directive in the .INC file so that MASM
correctly handles long integers within expressions. This means that the .INC files as
well as all the .ASM files which include .INC files created with H2INC will resolve
integer expressions in 32 bits instead of 16 bits.
This also means that if a negative number is evaluated in an expression, its value
can only be used as a double word (or longer) operand.
These C statements:
#define MINUS_1 (-1)
#define MINUS_2 -2
generate these MASM statements:
MINUS_1 EQU 0ffffffffh
MINUS_2 EQU -2t
In most cases, the second behavior is more desirable, as the decimal representation
can be cast within MASM to the appropriate size (with a word ptr operator, for
example)."
MASMGETa equ -88
GETb equ (-88)
GETc equ 88
GETd equ -88t
mov al, GETa
mov al, GETb
mov al, GETc
mov al, GETd
mov ax, word ptr GETa
mov ax, word ptr GETb
mov ax, word ptr GETc
mov ax, word ptr GETd
mov ax, byte ptr GETa
mov ax, byte ptr GETb
mov ax, byte ptr GETc
mov ax, byte ptr GETd
mov al, NOT(GETa)
mov al, NOT(GETb)
mov al, NOT(GETc)
mov al, NOT(GETd)
mov al, 0A8h
mov al, 0A8h
mov al, 58h ; 'X'
mov al, 0A8h
mov ax, 0FFA8h
mov ax, 0FFA8h
mov ax, 58h ; 'X'
mov ax, 0FFA8h
mov ax, 0FFA8h
mov ax, 0FFA8h
mov ax, 58h ; 'X'
mov ax, 0FFA8h
mov al, 57h ; 'W'
mov al, 57h ; 'W'
mov al, 0A7h
mov al, 57h ; 'W'
UASM mov al, 0A8h
_TEXT:00000087 mov al, 0A8h
_TEXT:00000089 mov al, 58h ; 'X'
_TEXT:0000008B mov al, 0A8h
_TEXT:0000008D mov ax, 0FFA8h
_TEXT:00000091 mov ax, 0FFA8h
_TEXT:00000095 mov ax, 58h ; 'X'
_TEXT:00000099 mov ax, 0FFA8h
_TEXT:0000009D mov ax, 0FFA8h
_TEXT:000000A1 mov ax, 0FFA8h
_TEXT:000000A5 mov ax, 58h ; 'X'
_TEXT:000000A9 mov ax, 0FFA8h
_TEXT:000000AD mov al, 57h ; 'W'
_TEXT:000000AF mov al, 57h ; 'W'
_TEXT:000000B1 mov al, 0A7h
_TEXT:000000B3 mov al, 57h ; 'W'
Once the numbers become negative, UASM can't work with them. Here it is required to make a mandatory casting of a variable using byte ptr, which makes no sense, because the register itself tells about the size of the variable. In any case, the object file becomes broken. :undecided: