News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Difference between jwasm and uasm

Started by tastewar, August 28, 2019, 05:12:27 AM

Previous topic - Next topic

tastewar

More background, if anyone is still interested. We have a large project we are working on. One piece is a language interpreter with a plugin architecture that in Windows uses dll's, and in Linux will hopefully use .so files. Currently, we are able to build and run the interpreter in 64 bit Linux using jwasm. It works fine. I'm not sure how any of it is "wrong" since it's a fairly complex program, and it builds and runs, and interacts with the underlying Linux OS just fine.

We have a trivial sample plugin, written in C and built as a .so that the interpreter can load and call. However, we have a large number of such plugins that are written in our proprietary language, and that language has a compiler that originally produced MASM source as its output. On Linux, we now have it producing jwasm source. Since jwasm is dead, and is incapable of producing .so files, we would definitely like to make the switch to uasm! Since it's supposed to be compatible, we just swapped in the executable, and tried calling it instead. But clearly, it's not quite compatible, because given the same source, it isn't producing the same assembly. Specifically, the "traditional" stack frame has gone missing.

I'm attaching a slightly larger example. This one has the original (proprietary) source in the Main64.txt file, the "compiled" ASM in Main64.asm, and the jwasm produced listing file in HelloWorld64CFJW.lst and the uasm produced listing in HelloWorld64CFU.lst. If you run a diff between them, you will see that the major, functional difference is the lack of the stack frame. jwasm produces a function that includes push rbp; mov rbp,rsp; sub rsp,1200 to make space for the locals. I don't see an adjustment in rsp for local variables in the uasm listing.

I apologize if I'm missing something completely obvious/elementary here, but we thought this would be a drop-in, and it's clearly not. My hope is there is some simple command line switch we can assert to have uasm produce functions with a stack frame. Or change something in the asm our compiler is emitting to get the same result.

Anyone?

jj2007

tastewar,

It seems that johnsa & habran, the two UAsm developers, are currently on holiday. They certainly will help you, even if that requires an entirely new option (but I don't think so). Few people here are familiar with Linux, so be patient, it's just a matter of a few days.

tastewar


aw27

You appear to have disregarded, but I have posted an example where an RBP stackframe is produced. UASM will not make a stackframe, unless it is necessary - that's why I included a LOCAL variable to force it.
You can keep trying to make a stackframe appear with FRAME: AUTO or FRAME:NOAUTO, but you will never see that miracle happen. I told you, FRAME is not for that.
I will not download and look at your code, it will not bring anything new in relationship with the stackframe problem and I can not spend time on lateral issues at the moment.

tastewar

I apologize, AW, if I didn't reply directly to your post. I certainly didn't try anything with the FRAME attribute after reading it. It may be that I posted a response that spoke about trying it, but that was before I read your post, even if it might have been after you posted it. I understand you may not have time to help me, and I certainly don't expect you to expend more effort on my issue than you feel is appropriate for you.

The second example I posted, which you are certainly free to continue to ignore, included local variables, and did not use a FRAME attribute, but produced no stack frame. So there must be more to it than that. Either we are asserting something on the command line or in our code that is causing uasm to not produce the frame, or we are failing to assert something that could. It's a difference between jwasm and uasm, and I am trying to learn what (if anything) we can do to get the older behavior, which definitely works with the bulk of our code. Also, for your (and others') information, unlike the first, the second example is not intended to produce a stand-alone runnable executable.

The first example I had posted would seg fault when built with uasm and run fine built with jwasm. I have years of experience debugging in Windows, but am very new to systems level programming on Linux, which makes it just more of a mystery.

Thanks for your contribution to the discussion!

Cheers,
--Tom

aw27

@tastewar  :biggrin:

I had a look at your code and could not believe that you were using stdcall in 64-bit  :skrewy:
It does not exist stdcall for 64-bit, if you see it somewhere, it is aliased for the standard which is:
System V AMD64 ABI

OK, UASM is not aliasing or producing an error - here you are right!  :eusa_clap:

Remove the stdcall and you will see the FRAME you want.

tastewar

Thank you, AW! I had a feeling that if the right person looked at it, they'd see what was wrong!

tastewar

Amusingly, removing STDCALL causes jwasm to yield an error (Main64.asm(79) : Error A2091: Language type must be specified) and it seems just as unhappy with SYSCALLV.

I think also that KradMoonRa was onto the problem, but I wasn't understanding.

I tried OPTION LANGUAGE:SYSTEMV which works for uasm, but jwasm doesn't like this either.

Can anyone think of a way for me to specify this that's compatible with both jwasm and uasm?

aw27

That is probably a JWASM bug that happens when there are parameters in the function. Use FASTCALL for JWASM and see  if the end result is not nonsense. I have not tested.
Use UASM for 64-bit, forget JWASM

hutch--

> Use UASM for 64-bit, forget JWASM

This is pretty much the action, JWASM was reasonably successful in 32 bit but Win64 uses a different ABI (Application Binary Interface) than the Intel ABI that was used in Win32 and JWASM did not do this correctly. You should NOT be using STDCALL push/call notation in 64 bit as the 64 bit system does not support it correctly.

I am familiar with this stuff in Win64 as I use the 64 bit version of MASM and had to construct the macros to do all of this. There is the first 4 stack locations that are termed "shadow space" which are filled from the 4 registers, RCX RDX R8 and R9 then any following arguments are written to the stack locations after the shadow space.

I have tested UASM with near identical code to 64 bit MASM and it performs correctly so it is properly using the Win64 ABI.

tastewar


jj2007

If you want to keep compatibility with JWasm during the transition:

      ifdef __UASM__
         echo ** the following options are for UAsm only **
      else
         echo ** the following options are for JWasm only **
      endif

KradMoonRa

#27
@tastewar, Yes with JWasm using other convention name like stdcall syscal fastcal, get's ignored and defaults to systemv. With UASM that don't happens, it gets an generic epilogue prologue wen other convention is written on procedure.

Has we probably gonna have another convention for 64bits the Intel regcall, the best thing to make UASM more JWasm friendly, or (better) fix the bug,  is if in 64 bit unix* {(if callconv != systemv ||  callconv != regcall) calconv = systemv;}, hallways defaults to systemv if also declaring other (syscall, fastcall, stdcall).

And get some TODO work wen working with kernel code, because.

User-level applications use as integer registers for passing the sequence
%rdi, %rsi, %rdx, %rcx, %r8 and %r9. The kernel interface uses %rdi,
%rsi, %rdx, %r10, %r8 and %r9.

Better explained in section A.2 AMD64 Linux Kernel Conventions in https://github.com/hjl-tools/x86-psABI/wiki/x86-64-psABI-1.0.pdf
The uasmlib

nidud

#28
deleted

KradMoonRa

@nidud
True, it's by the programmer to. In some old kernel linux distributions, any code has capable of running regarding off the caller. Currently we need to be magician to get the code running on recent linux kernel.

@tastewar
Regarding wath I talk earlier. Applied changes in uasm to ignore syscall cdecl stdcall wen use64 segment procedures on 64bits unix linux machos and defaults to SYSTEMV

Tested and built your HelloWorld got the results for mov rbp, rsp.

This is my test development branch, what's implemented were can change later or not be implemented in the release uasm.
64bits uasm build with windows and ubuntu 18.04
https://github.com/eXOAMP/UASM/releases/download/eX_v2.50_master_alpha0/Uasm_master.7z

With this version can be find the regcall for 32bits and 64bits windows, unix, linux, machos. thiscall for 32bits windows, windows vectorcall for bout 64bits and 32bits (invoke needs work on the implementation).

SYSTEMV
REGCALL
VECTORCALL
THISCALL

Info about Intel regcall https://software.intel.com/en-us/cpp-compiler-developer-guide-and-reference-c-c-calling-conventions
The uasmlib