Terraspace / UASM

UASM - Macro Assembler
http://www.terraspace.co.uk/uasm.html
Other
221 stars 49 forks source link

MSYS2 version of UASM produces an error with a simple mov instruction #202

Open sejtano opened 7 months ago

sejtano commented 7 months ago

This instruction produces an error on the MSYS2 version of UASM (UASM v2.56, Nov 12 2022):

mov ah,0ffh

Error A2048: Operands must be the same size: 1 - 4

mov ax,0ffh

Error A2048: Operands must be the same size: 2 - 4

It does work on the Windows version of UASM

TheRustifyer commented 7 months ago

@sejtano I'm interested on tracking this issue, since I am facing the same problem

sejtano commented 7 months ago

@TheRustifyer We can try looking into it then, unless someone from the project can solve it.

I tried the binaries for win32 and win64 of UASM and those don't have this problem.

I think, this issue comes from parser.c This file would be my starting point, if I could compile it.

What compiler do they use to create the MSYS2 version?

I tried compiling UASM with mingw32's gcc, using the makefile GccWin.mak It gave me 2 errors during compilation in the file dbgcv.c. It is a problem of conversion between : 'char ' and 'uint_8 ' It looks like it can be fixed by type casting.

The bigger problem is that once I did that, the linker gave me countless errors.

TheRustifyer commented 7 months ago

@sejtano I tried to compile them in both Linux and Windows, and none of the Makefiles was suitable for my Clang compilers. Those Makefiles are for compilers like clang-3.x, but I think that the code is outdated for such newer compiler versions

sejtano commented 7 months ago

@TheRustifyer I think I found the problem. As I suspected, this seems to be a unsigned/signed mismatch.

First of all, I was able to compile the code using gcc 12.2 for MinGW32, which is the version I am using. I used gccwin.mak.

The code gave me a few warnings and two errors. The errors were about char and uint_8. I typecasted them into char in the dbgcv.c file. dbgcv.c seems to generate debugging info in CodeView format, which shouldn't be a problem here, but maybe should be looked at more carefully.

The linker needed the --allow-multiple-definition flag to produce a workable executable. It can be added to gcc as -Xlinker --allow-multiple-definition Apparently they changed things in gcc 10, so if you use gcc 9 or so, maybe it would just compile.

The problem I found was in parser.c, in the function _idatanofixup() in the line 1031: if ( (int_8)value == value ) one is a signed char the other one as unsigned char or short.

This is the part of the code:

else 
{
    /* use true signed values for BYTE only! */
    if ( (int_8)value == value )
        op_type = OP_I8;
    else if( value <= USHRT_MAX && value >= 0L - USHRT_MAX )
        op_type = OP_I16;
    else 
        op_type = OP_I32;
}

Fixing it requires a small change, but I don't know if this has other implications. You can change it into something that would work here: if ((unsigned char)value == value )

Both sides should be 8bit unsigned numbers.

With this change the instruction mov ah,0ffh doesn't give errors and UASM generates the right code for this instruction. I didn't do more testing for now. Maybe something more robust has to be done here to fix the problem properly.

valium007 commented 6 months ago

use mingw gcc-7 compiler, also i patched that code and the assembler compiles fine without any errors

valium007 commented 6 months ago

@sejtano you can also use just the -fcommon flag in gcc to enable multiple definitions no need to pass linker flags

john-terraspace commented 3 months ago

Correcting and testing signed/unsigned comparison in 2.57.