有没有一种方法可以通过Web Assembly用内联汇编语言编译C文件?
emcc(模仿gcc / clang的替换语言+模仿GNU ld的链接器)1.38.12
尝试编译时:
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;
}
这些是错误:
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
还编译了这个C文件:
int main(){
int test();
test()
}
已链接到该Assembly文件:
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
这些是错误:
warning: unexpected number of arguments 0 in call to 'test', should be 1
warning: unresolved symbol: test
谢谢。
答案 0 :(得分:2)
asm局部变量只能保证在GNU C中与Extended asm语句一起使用。您正在将它们与Basic asm一起使用,这可能会起作用,但不能保证。 (https://gcc.gnu.org/onlinedocs/gcc/Local-Register-Variables.html
仅使用"a"(1UL)
之类的约束在RAX中放置1
就是毫无意义的。同样不要因为syscall
的工作原理而在RCX和R11上声明clobbers,而RAX也是输出。
无论如何,当编译为与平台无关/与架构无关的 web 组件而不是直接编译为x86 asm时,x86特定的寄存器名称当然将不起作用。
在将webasm转换为本机代码时,在ARM CPU上运行的浏览器将没有这些寄存器可用。即使是针对32位x86编译的浏览器也没有这些寄存器。
此外,在x86-64 Windows上运行的浏览器将提供这些寄存器,但Linux系统调用的ABI将不起作用。
AFAIK,即使您唯一的目标是可以工作的目标,也无法将目标特定的嵌入式asm和特定寄存器包装在网络asm中。设计来支持它。
运行gcc或clang时,目标是WASM,不是 x86。