#assembly #assemble #dynasm

direct-asm

用于内联汇编的自定义汇编器

1个不稳定版本

0.0.1-alpha2020年7月2日

#20 in #assemble

Download history 108/week @ 2024-04-04 153/week @ 2024-04-11 103/week @ 2024-04-18 76/week @ 2024-04-25 102/week @ 2024-05-02 123/week @ 2024-05-09 108/week @ 2024-05-16 115/week @ 2024-05-23 122/week @ 2024-05-30 167/week @ 2024-06-06 105/week @ 2024-06-13 98/week @ 2024-06-20 145/week @ 2024-06-27 165/week @ 2024-07-04 200/week @ 2024-07-11 300/week @ 2024-07-18

813 每月下载次数
用于 syscall-linux-raw

Unlicense许可证

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