1个不稳定版本
0.0.1-alpha | 2020年7月2日 |
---|
#20 in #assemble
813 每月下载次数
用于 syscall-linux-raw
29KB
618 行
direct-asm
一个Rust进程宏,用于将预汇编指令作为函数调用包含在内。
是什么
use libc::{c_int, c_void, size_t, ssize_t, c_long};
// Call write as a syscall on SysV x86-64 abi.
// WIP: The constant SYS_write needs to be provided by the caller for now.
#[direct_asm::assemble]
unsafe extern "C"
fn sys_write(fd: c_int, ptr: *const c_void, len: size_t, wcall: c_long)
-> ssize_t
{
"mov rax, rcx"; // Move sys call number to rax as required
// Other arguments are already in correct register
"syscall"; // Invoke actual system call placed in rax
"ret" //Return actual result
}
fn sys_print(what: &str) -> libc::ssize_t {
unsafe {
sys_write(1, what.as_ptr() as *const libc::c_void, what.len(), SYS_write)
}
}
为什么
为了提供一个替代gcc中inline-asm
的方案,可能具有更精细的语义控制。这不足以满足所有目的,但对于读取堆栈寄存器、进行系统调用(我想应该是这样)以及更多功能是足够的。包含的代码必须是位置无关的,不能访问全局变量(应作为参数传递),并且不能引入任何新符号。
如何
通过使用#[no_mangle]
滥用,将两个定义进行别名操作。我们使用nasm
预编译asm,将其转换为原始二进制形式,然后在.text
部分定义一个包含此代码的静态字节数组,最后定义一个具有相同符号名称的extern "C"
函数。然后链接器将解析该函数到数组定义,从而调用预期中的代码。
什么鬼
的确。不要在生产环境中使用。
演示?
在minimal-rust
文件夹中,我们在稳定Rust上构建了一个186字节的二进制文件。
许可证
基础软件:Unlicense
修改后的dynasm
后端:Mozilla Public License Version 2.0
依赖关系
~2MB
~49K SLoC