递归删除x64程序集中的文件

时间:2019-03-10 20:55:21

标签: linux assembly posix x86-64 system-calls

因此,我需要使用x86_64程序集递归删除目录中的文件。 这是我的代码,我知道这很不好。我的问题是每个syscall都可以单独工作(我可以单独删除目录或文档),但是一旦我像这样将它们合并在一起,它就无法工作。 #edit:正如@fuz指出的那样,该问题的描述性不够。因此,我希望它打开包含名为“ test.txt”的文件的目录,删除该文件,然后删除包含该文件的目录。但是当我使用nasm编译它时,它只是退出了程序。我正在使用Linux Mint

global _start

section .text

_start:


;open directory
    mov rax,    2       ;sys_open
    mov rdi,    dir     ;pointer to the directory
    mov rsi,    0       ;read only
    syscall


;delete document
    mov rax,    87      ;sys_unlink
    mov rdi,    doc     ;points to the document
    syscall


;delete directory
    mov rax,    84      ;sys_rmdir
    mov rdi,    dir
    syscall


_exit:
    mov rax,    60
    mov rdi,    80
    syscall


section .data
dir: db 'test',0
doc: db 'test.txt',0

1 个答案:

答案 0 :(得分:3)

您的问题不在于汇编,而在于理解基本的POSIX / Unix文件操作系统调用。 open("dir")以后不会相对于该目录进行unlink / rmdir系统调用,它们仍然相对于您当前的工作目录。您可以使用chdir()进行更改。

(使用C比使用asm更容易。对于大多数系统调用而言,glibc包装器是微不足道的,并将所有args不变地传递给内核。如果不是这种情况,请参见Linux手册页的NOTES部分记录下来。)


个系统调用,它们执行与打开的目录文件描述符(而不是CWD)相关的事情,其名称在文件名后添加了...at后缀。传统的系统调用名称。该文档使用C语法来描述系统调用,但是在ABI的指导下,它告诉您如何在asm中调用它们。

  • unlinkat(int dirfd, const char *pathname, int flags)
  • fli-relative rmdir实际上是用unlinkat(fd, path, AT_REMOVEDIR)完成的。 (否则,对于flags=0,unlinkat的行为类似于常规的unlink。)
  • linkatsymlinkatreadlinkatstatatmkdiratexecveat,...
  • 其他各种类型,包括renameat和一个有趣的renameat2,它带有标志,允许您在同一文件系统上原子地交换两个路径名。

  • notes section of the openat man page解释了为什么这些at系统调用首先存在于Rationale for openat()下-避免了其他人rename在readdir和open之间的竞争情况路径的目录组件。而且由于chdir()是按进程而不是按线程的,因此允许不同的线程同时在不同目录中执行相对的工作。


就像Jester所说的那样,请使用 strace find test -name 'test.txt' -delete 或类似的方法来查看如何通过open(O_DIRECTORY)getdents和{{1} }。

getdents是在Linux上基于POSIX unlinkat接口构建的原始系统调用。手册页对此进行了记录。在asm中,您可以使用对readdir的libc函数调用,也可以自己使用readdir


或者由于您实际上并不是递归,只需对一些相对路径进行硬编码,您就可以进行getdentsunlink("test/test.txt")系统调用。