Web Assembly 编译 C 文件时出现内联汇编语言错误
Web Assembly compile C file with inline Assembly Language error
有没有办法用 Web Assembly 编译带有内联汇编语言的 C 文件?
emcc(Emscripten gcc/clang-like 替换 + 模拟 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()
}
链接到此程序集文件:
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
谢谢。
asm 局部变量只能保证与 GNU C 中的扩展 asm 语句一起使用。您将它们与 Basic asm 一起使用,这可能会碰巧起作用但不能保证。 (https://gcc.gnu.org/onlinedocs/gcc/Local-Register-Variables.html
当您可以使用 "a"(1UL)
之类的约束将 1
放入 RAX 时,这毫无意义。也不要忘记在 RCX 和 R11 上声明 clobber,因为 syscall
是如何工作的,而且 RAX 也是一个输出。
无论如何,当编译为可移植平台中立/体系结构中立的 web 程序集而不是直接编译时,特定于 x86 的寄存器名称当然不起作用x86 汇编。
在 ARM CPU 上运行的浏览器 运行 在将 webasm JITing 到本机代码时,这些寄存器将不可用。即使是为 32 位 x86 编译的浏览器也不会有这些寄存器。
此外,在 x86-64 Windows 上的浏览器 运行ning 将提供这些寄存器,但 Linux 系统调用 ABI 将不起作用。
AFAIK,您不能将目标特定的内联 asm 和特定寄存器包装在 web-asm 中,即使您唯一的预期目标是它们可以工作的地方。 web- asm 语言并非旨在支持它。
当你运行 gcc 或 clang 时,目标是 WASM,不是 x86.
有没有办法用 Web Assembly 编译带有内联汇编语言的 C 文件?
emcc(Emscripten gcc/clang-like 替换 + 模拟 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()
}
链接到此程序集文件:
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
谢谢。
asm 局部变量只能保证与 GNU C 中的扩展 asm 语句一起使用。您将它们与 Basic asm 一起使用,这可能会碰巧起作用但不能保证。 (https://gcc.gnu.org/onlinedocs/gcc/Local-Register-Variables.html
当您可以使用 "a"(1UL)
之类的约束将 1
放入 RAX 时,这毫无意义。也不要忘记在 RCX 和 R11 上声明 clobber,因为 syscall
是如何工作的,而且 RAX 也是一个输出。
无论如何,当编译为可移植平台中立/体系结构中立的 web 程序集而不是直接编译时,特定于 x86 的寄存器名称当然不起作用x86 汇编。
在 ARM CPU 上运行的浏览器 运行 在将 webasm JITing 到本机代码时,这些寄存器将不可用。即使是为 32 位 x86 编译的浏览器也不会有这些寄存器。
此外,在 x86-64 Windows 上的浏览器 运行ning 将提供这些寄存器,但 Linux 系统调用 ABI 将不起作用。
AFAIK,您不能将目标特定的内联 asm 和特定寄存器包装在 web-asm 中,即使您唯一的预期目标是它们可以工作的地方。 web- asm 语言并非旨在支持它。
当你运行 gcc 或 clang 时,目标是 WASM,不是 x86.