如何使用asm的errno?

时间:2017-06-02 02:10:48

标签: linux assembly

我正在尝试在64位Linux系统上创建一个小型可执行文件。我需要做的就是从stdin读取并写入stdout所以我认为缩小它的好方法可能是避免使用libc并静态链接我自己的函数,这将直接调用read(2)和write(2)系统调用代替。 (事实证明我也需要退出(2)。)因此,经过一些实验,我想出了以下汇编程序代码,我将其与用C编写的其余程序链接。

除了一件事之外,它主要起作用。 libc函数在发生错误时包装读写set errno。我不能让这个工作。对于这个特定的项目来说没什么大不了的,但是如果我决定在这些功能之上编写一个mini-stdio,这将是非常重要的。所以这是代码。你能告诉我哪里出错了吗?

.global sys_exit
.global sys_read
.global sys_write
.global errno

.text
sys_exit:
    movq $60, %rax  # exit syscall = 60
    syscall
    ret

sys_read:
    movq $0, %rax   # read syscall = 0
    syscall
    jc error
    ret

sys_write:
    movq $1, %rax   # write syscall = 1
    syscall
    jc error
    ret

error:
    movl $60, errno
    ret

.bss
errno: .INT 0

这是一个使用这些功能的示例c程序:

#define stdin 0
#define stdout 1
extern int errno;

void _start() {
    char c;

    if (sys_read(stdin, &c, 1) < 0) {
        sys_exit(errno);
    }

    if (sys_write(stdout, &c, 1) < 0) {
        sys_exit(errno);
    }

    sys_exit(0);
}

更新

好的,经过多次阅读后我觉得我现在有了它:

.global sys_exit
.global sys_read
.global sys_write
.global errno

.text
sys_exit:
    movq $60, %rax  # exit syscall = 60
    syscall
    ret

sys_read:
    movq $0, %rax   # read syscall = 0
    syscall
    cmpl $0, %eax
    jl error
    ret

sys_write:
    movq $1, %rax   # write syscall = 1
    syscall
    cmpl $0, %eax
    jl error
    ret

error:
    neg  %eax
    movl %eax, errno
    movl $-1, %eax
    ret

.bss
errno: .INT 0

感谢所有回复的人。

0 个答案:

没有答案