VOGONS


First post, by Exploit

User metadata
Rank Newbie
Rank
Newbie

If have the following assembler code, see screenshots.

And when i try to compile it, i get the following error:
Error A2189: Constant or relocatable label expected

It must have something to do with the IF..ELSE statements in the MACRO file.
When i remove them, the code compiles.

But i need them for my project. So what is the correct way to use them with JWASM, so that there are no more this error message?

I searched in the manual, but didn't find a solution.
https://www.japheth.de/JWasm/Manual.html

Attachments

  • mtest_error.png
    Filename
    mtest_error.png
    File size
    5.97 KiB
    Views
    1172 views
    File license
    Fair use/fair dealing exception
  • mtest_inc.png
    Filename
    mtest_inc.png
    File size
    5.5 KiB
    Views
    1172 views
    File license
    Fair use/fair dealing exception
  • mtest_asm.png
    Filename
    mtest_asm.png
    File size
    3.96 KiB
    Views
    1172 views
    File license
    Fair use/fair dealing exception

Reply 1 of 17, by dunzdeck

User metadata
Rank Newbie
Rank
Newbie

I've never used JWASM but some things that come to mind:
- doesn't the 'Reg8' parameter need some kind of affix? Like "@Reg8"? I seem to remember this from old TASM days.
- are you defining the macro in keeping with JWASM's manual? See the example in section 3.17 of the link you posted.
- the error refers to the UPC macro. What happens if you comment out the part where it is called? The 'UPC BH' line.
- what happens if you just inline the macro?

Reply 2 of 17, by vstrakh

User metadata
Rank Member
Rank
Member

Looking at my old TASM code, it's just could be possible that you need to wrap Reg8 parameter name in some brackets in the IF statement, but only within that statement. You did wrap BL already in round brackets, same could be required for Reg8 too.
TASM required angle brackets, the macro did look like this:

macro paramstr parm
ifdifi <parm>,<ax>
mov ax,parm
endif
; ... blah-blah...
endm

Reply 3 of 17, by Exploit

User metadata
Rank Newbie
Rank
Newbie
dunzdeck wrote on 2022-10-24, 15:43:

I've never used JWASM but some things that come to mind:
- doesn't the 'Reg8' parameter need some kind of affix? Like "@Reg8"? I seem to remember this from old TASM days.
- are you defining the macro in keeping with JWASM's manual? See the example in section 3.17 of the link you posted.

I don't know if there is an affix necessary. I got the syntax mainly from an assembler book written for MASM and I'm trying to adapt my code to JWASM.

Using

IF (Reg8 EQ @BL)

doesn't work and gives the error message:

Error A2102: Symbol not defined: @BL

- the error refers to the UPC macro. What happens if you comment out the part where it is called? The 'UPC BH' line.

The error is in the IF..ELSE section inside the UPC macro. If i comment out all the IF...ELSE stuff, then it assembles without errors.

- what happens if you just inline the macro?

The error stays the same.

Reply 4 of 17, by Exploit

User metadata
Rank Newbie
Rank
Newbie
vstrakh wrote on 2022-10-24, 17:59:
Looking at my old TASM code, it's just could be possible that you need to wrap Reg8 parameter name in some brackets in the IF st […]
Show full quote

Looking at my old TASM code, it's just could be possible that you need to wrap Reg8 parameter name in some brackets in the IF statement, but only within that statement. You did wrap BL already in round brackets, same could be required for Reg8 too.
TASM required angle brackets, the macro did look like this:

macro paramstr parm
ifdifi <parm>,<ax>
mov ax,parm
endif
; ... blah-blah...
endm

I tested now:

IF ("Reg8" EQ "BL")

This gets assembled, but the output is not correct. (uses the ELSE statement)

IF ((Reg8) EQ (BL))

Leads to the same E2189 error.

IF ([Reg8] EQ [BL])

Leads to:

ERROR: A2033: Must be index or base register

and

IF ({Reg8} EQ {BL})

Leads to:

ERROR: A2151: Unexpected literal found in expression: {BL] EQ {BL})

Reply 5 of 17, by Exploit

User metadata
Rank Newbie
Rank
Newbie

I simplified the code a little bit just for testing.

If you want to do some test for yourself, just rename
MTEST_INC.TXT to MTEST.INC
and
MTEST_ASM.TXT to MTEST.ASM

IF (<Reg8> EQ <BL>) 

Also doesn't work:

ERROR: A2151: Unexpeteced literal found in expression: <BL> EQ <BL>)

The good thing is, Reg8 gets at least substituted by BL.
Now i need to find a way to compare BL with BL by using EQ in the IF statement.

Attachments

  • Filename
    MTEST_INC.TXT
    File size
    393 Bytes
    Downloads
    41 downloads
    File license
    Public domain
  • Filename
    MTEST_ASM.TXT
    File size
    400 Bytes
    Downloads
    42 downloads
    File license
    Public domain
  • mtest_asm_simplified.png
    Filename
    mtest_asm_simplified.png
    File size
    7.86 KiB
    Views
    1131 views
    File license
    Fair use/fair dealing exception

Reply 7 of 17, by Exploit

User metadata
Rank Newbie
Rank
Newbie

I agree. I've just tried the brute force method because I'm running out of options. 😉

The manual mentions upercase IF and ELSE and other key words in the Appendix A. JWasm Reserved Words chapter at least.
But how to use them with JWASM and register names? That's the big question. Is it not supported? Is it a bug?
https://www.japheth.de/JWasm/Manual.html#AA

Reply 8 of 17, by vstrakh

User metadata
Rank Member
Rank
Member

I'm not sure what are you doing, because it works exactly the same as in TASM, which in turn follows the MASM rules.
Here's with case-insensitive IF comparison:

	.model small
.stack 256

upc macro Reg8
ifidni <Reg8>,<BL>
mov Reg8, 35h
else
mov Reg8, 39h
endif
endm

.code

UPC bh
UPC ax
UPC bl

end

Compiling it with -EP option to get the preprocessed listing I get the following output in the console:

C:\ASM\jwasmr.exe -EP j.asm
.model small
.stack 256
.code
mov bh, 39h
mov ax, 39h
mov bl, 35h
end
mov bh, 39h
mov ax, 39h
mov bl, 35h

Note the BL branch is taken for bl register, and the other branch is taken for all the other registers, just what you tried to achieve.

Reply 9 of 17, by vstrakh

User metadata
Rank Member
Rank
Member

Your issue with EQ might be related to data types expected by this operator.
TASM manual say the EQ treats its arguments as unsigned numbers. I'd guess the same applies to MASM, so EQ should not be used for texts comparison.

Reply 10 of 17, by Exploit

User metadata
Rank Newbie
Rank
Newbie
vstrakh wrote on 2022-10-24, 20:07:

I'm not sure what are you doing, because it works exactly the same as in TASM, which in turn follows the MASM rules.

Well

	ifidni <Reg8>,<BL>

and

	if (Reg8 EQ BL)

do have a different key word and syntax and are not the same.

The latter is an example from the assembler book i am reading which is written for MASM. Thus, this works in MASM.
JWASM trys to be compatible to MASM, but it seems that here the compatibility ends.

Your

	ifidni <Reg8>,<BL>

is a completely other solution. And yes it works. But how should i know that, when my MASM books says i should use

	 IF (PART1 Operator PART2)

?

With one of the following operators:
EQ = equal
NE = not equal
LT = less than
LE = less or equal
GT = greater
GE = greather or equal

And where PART1 and PART2 can be registers.

Here's with case-insensitive IF comparison:

Thanks.

Note the BL branch is taken for bl register, and the other branch is taken for all the other registers, just what you tried to achieve.

Exactly.
But it doesn't work with this MASM syntax in JWASM, at least not when using a register. It seems to work with other things like constants.

Last edited by Exploit on 2022-10-24, 20:41. Edited 2 times in total.

Reply 11 of 17, by Exploit

User metadata
Rank Newbie
Rank
Newbie
vstrakh wrote on 2022-10-24, 20:14:

Your issue with EQ might be related to data types expected by this operator.
TASM manual say the EQ treats its arguments as unsigned numbers. I'd guess the same applies to MASM, so EQ should not be used for texts comparison.

No, MASM eats this. The book and its examples are written for MASM.

But it seems to be this could be true:

TASM manual say the EQ treats its arguments as unsigned numbers. I'd guess the same applies to MASM JWASM, so EQ should not be used for texts comparison.

Reply 12 of 17, by Exploit

User metadata
Rank Newbie
Rank
Newbie

It's also a pitty, that the JWASM manual doesn't mention, that i should use ifidni instead of if ( ... EQ ...).

By MASM book has also only about 300 pages with a large font size. ifidni isn't even mentioned in the book.

Reply 13 of 17, by Exploit

User metadata
Rank Newbie
Rank
Newbie

One more question

Can you tell me, which if##### key word corresponds to which if operator of the following list?

EQ = equal  
NE = not equal
LT = less than
LE = less or equal
GT = greater
GE = greather or equal

Now i know, that ifidni <parm1>, <parm2> can be used instead of IF ( parm1 EQ parm2..).
But the others?

Reply 14 of 17, by vstrakh

User metadata
Rank Member
Rank
Member
Exploit wrote on 2022-10-24, 20:33:

It's also a pitty, that the JWASM manual doesn't mention, that i should use ifidni instead of if ( ... EQ ...).

By MASM book has also only about 300 pages with a large font size. ifidni isn't even mentioned in the book.

This is the link to MASM reference, here's the 'ifidni' directive:
https://learn.microsoft.com/en-us/cpp/assembl … n?view=msvc-170

Now EQ is a relational operator, comparing results of two expressions.
See this:
https://learn.microsoft.com/en-us/windows-har … c---expressions

In an MASM expression, the numeric value of any symbol is its memory address. In a C++ expression, the numeric value of a variable is its actual value, not its address. Data structures do not have numeric values. Instead, they are treated as actual structures and you must use them accordingly. The value of a function name or any other entry point is the memory address and is treated as a function pointer. If you use a symbol that does not correspond to a C++ data type (such as an unmodified module name), a syntax error occurs.

The MASM expression evaluator treats all numbers as ULONG64 values. The C++ expression evaluator casts numbers to ULONG64 and preserves type information of all data types.

This hints that result of expression is always a number. If something is not a number, then it's a symbol, and the value of such expression is the address of the symbol. That's why JWASM could not immediately tell "this is not a number", it hoped to find the address of the symbol, that's why the warning message say it wanted "a constant or relocatable item".

The JWASM can't recommend one operator over another, it's assumed you know the rules and use appropriate operators or directives.

Reply 15 of 17, by vstrakh

User metadata
Rank Member
Rank
Member
Exploit wrote on 2022-10-24, 20:38:
Can you tell me, which if##### key word corresponds to which if operator of the following list? […]
Show full quote

Can you tell me, which if##### key word corresponds to which if operator of the following list?

EQ = equal  
NE = not equal
LT = less than
LE = less or equal
GT = greater
GE = greather or equal

Now i know, that ifidni <parm1>, <parm2> can be used instead of IF ( parm1 EQ parm2..).
But the others?

Did you notice the 'i' at the end of 'ifidni'? This means case-insensitive. The case sensitivity does not apply to numbers. EQ/NE/LT/LE/GT/GE - it's all relational operators, they compare numbers obtained after evaluating the expressions. Now 'ifidni', 'ifdif' - are the directives, doing something else than IF. It does not take the expression, it operates on some other conditions. These do not mix, and not an alternatives of each other.

Reply 16 of 17, by Exploit

User metadata
Rank Newbie
Rank
Newbie

Thanks.

vstrakh wrote on 2022-10-24, 20:53:

This hints that result of expression is always a number. If something is not a number, then it's a symbol, and the value of such expression is the address of the symbol. That's why JWASM could not immediately tell "this is not a number", it hoped to find the address of the symbol, that's why the warning message say it wanted "a constant or relocatable item".

MASM uses the @ sign to tell MASM that a register is a register and not a hexadecimal number.
So

IF (param1 EQ BL)

should be better written as:

IF (param1 EQ @BL)

But JWASM doesn't accept that either.
The value of a register should be treated as a number in this case. MASM does this at least.

The JWASM can't recommend one operator over another, it's assumed you know the rules and use appropriate operators or directives.

Yes, it seems so. MASM provides at least the @ sign to make clear if AH is a name of a register or a hexadecimal number.

Reply 17 of 17, by Exploit

User metadata
Rank Newbie
Rank
Newbie

Thanks.

vstrakh wrote on 2022-10-24, 20:58:

Did you notice the 'i' at the end of 'ifidni'? This means case-insensitive. The case sensitivity does not apply to numbers. EQ/NE/LT/LE/GT/GE - it's all relational operators, they compare numbers obtained after evaluating the expressions.

I wasn't referring about the is case sensitive and is not case insensitive issue.

I asked what directive is the replacement for the following operators.

if (a>b)
if(a>=b)
if (a<b)
if (a<=b)
if (a!=b)
if(a==b) // that's ifidni

Now 'ifidni', 'ifdif' - are the directives, doing something else than IF. It does not take the expression, it operates on some other conditions. These do not mix, and not an alternatives of each other.

Well, what i learned today is. That i can't use IF in JWASM when using registers. I must use ifidni (EQ) and other directives (for the other operators NE/LT/LE/GT/GE) .

So for

if (xy EQ @register)  ;MASM

i must use the directive

ifidni <xy>, <register> ;JWASM

as an alternative.