Web Assembly compile C file with inline Assembly Language error

3423 views javascript
6

Is there a way to compile a C file with inline Assembly Language with Web Assembly?

emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 1.38.12

When trying to compile this:

int main(void) {
  register int    syscall_no  asm("rax") = 1;
  register int    arg1        asm("rdi") = 1;
  register char*  arg2        asm("rsi") = "hello, world\n";
  register int    arg3        asm("rdx") = 14;
  asm("syscall");
  return 0;
}

These are the errors:

test.c:2:35: error: unknown register name 'rax' in asm
  register int    syscall_no  asm("rax") = 1;
                              ^
test.c:3:35: error: unknown register name 'rdi' in asm
  register int    arg1        asm("rdi") = 1;
                              ^
test.c:4:35: error: unknown register name 'rsi' in asm
  register char*  arg2        asm("rsi") = "hello, world!\n";
                              ^
test.c:5:35: error: unknown register name 'rdx' in asm
  register int    arg3        asm("rdx") = 14;
                              ^
4 errors generated.
ERROR:root:compiler frontend failed to generate LLVM bitcode, halting

Also compiled this C file:

int main(){
    int test();
    test()
}

That is linked to this Assembly file:

SECTION .text
            GLOBAL test

            test:
                mov rax,1     
                mov rdi,1   
                mov rsi,name 
                mov rdx,7 
                syscall


                mov rax,60   
                mov rdi,0  
                syscall

    SECTION .data
        name DB "Hello",10

These are the errors:

warning: unexpected number of arguments 0 in call to 'test', should be 1
warning: unresolved symbol: test

Thank you.

answered question

1 Answer

10

asm local variables are only guaranteed to work with Extended asm statements in GNU C. You're using them with Basic asm, which may happen to work but is not guaranteed. (https://gcc.gnu.org/onlinedocs/gcc/Local-Register-Variables.html

And it's pointless when you could just use constraints like "a"(1UL) to put a 1 in RAX. Also don't forget to declare clobbers on RCX and R11 because of how syscall works, and that RAX is also an output.


Anyway, of course x86-specific register names won't work when compiling to portable platform-neutral / architecture-neutral web assembly instead of directly to x86 asm.

A browser running on an ARM CPU won't have those registers available when JITing webasm into native code. Even a browser compiled for 32-bit x86 won't have those registers.

Also, a browser running on x86-64 Windows will have those registers available, but Linux system-call ABIs won't work.

AFAIK, you can't wrap target-specific inline asm and specific registers in web-asm even if your only intended target is one where they would work. The web-asm language isn't designed to support it.

When you run gcc or clang, the target is WASM, not x86.

posted this

Have an answer?

JD

Please login first before posting an answer.