linux - 文件名是否代表一个目录

标签 linux assembly x86 nasm

我有以下程序。它的目的是检查一个文件名是否代表一个目录,如果它是一个目录就设置进位标志,否则清除它。

现在它适用于我测试过的文件和目录,但我怀疑这只是巧合,因为我找不到任何关于 stat() 函数的有用文档,所以我不得不进行猜测。

我需要知道的是我可以在结构中的哪个偏移处找到文件是否是目录,以及哪个值表示什么。从我的测试中,我发现我所有的测试文件在偏移量 20 处的值为 1,而目录有 2 或 3,但这可能只是巧合,我不知道偏移量 20 处的值实际代表什么。可以是任何东西,也可以什么都不是。

此外,我为该结构预留了 100 个字节,但我怀疑这可能是太多内存了。同样,我真的可以为此使用一些与汇编而不是 C 相关的文档。那里的一切都是关于 C 的,我能做的最好的事情就是猜测。

...

[SECTION .bss]
StatBuf     resb 100

...

isdir:
    pushad

    push StatBuf
    push eax                ; Filename passed in eax
    call stat
    add esp, 8

    cmp eax, 0              ; stat returns 0 on success
    jne .error              ; -1 (not 0) on failure

    mov eax, StatBuf    ; Stats stored in StatBuf

    cmp byte [eax+20], 1    ; Guess: All files have value 1 at offset 20?
    jne .yes                ; Guess: Dirs either 2 or 3?

    clc                     ; Not a directory
    jmp .done

    .yes:
        stc                 ; File is a directory
        jmp .done

    .error:
        clc                 ; Error, not a directory
        jmp .done

    .done:
        popad
        ret

更新 0 我现在执行以下操作,它似乎再次起作用,但我不确定它是否真的正确。在 之后的 ebx 中的值对于文件似乎是 0,对于目录似乎是 64,难道不应该是相反的(目录为 0)吗?

mov eax, StatBuf

mov ebx, dword [eax+17]
and ebx, 0x40

cmp ebx, 0
jne .yes

最佳答案

您想检查 S_IFDIR in the st_mode member .这是第三个成员,应该是 [16]th 和 [23]rd 字节之间的单个位值(它被定义为掩码)。我会提供更多信息,但我现在正在使用 Windoze 框。

更新0

#include <sys/stat.h>
#include <stdio.h>
#include <stddef.h>

main() {
    printf("st_mode offset = %zu\n", offsetof(struct stat, st_mode));
    printf("S_IFDIR mask = %x\n", S_IFDIR);
}

执行给我:

matt@stanley:~$ gcc -o mask /home/matt/Desktop/mask.c
matt@stanley:~$ ./mask 
st_mode offset = 24
S_IFDIR mask = 4000

由于机器是小尾数法,这告诉我们如果设置了第 25 个字节的第二个最高有效位,它就是一个目录。在汇编中你应该读取这个字节[eax+25]它与0x40,然后与零比较。

或者你可以学习 C。

更新1

以上是在 x86_64 操作系统上执行的。该位置在 x86 上会有所不同。

更新2

和 ebx 0x40 之后的 ebx 的值如果是目录则为非零。

同样,如果您使用 C,则无需担心您的平台是什么。但是,如果您为 32 位操作系统编译程序,如果该操作系统支持 32 位二进制文​​件,它仍然可以在 64 位操作系统下正确运行。如果您在汇编中这样做,我会选择这条路线。

关于linux - 文件名是否代表一个目录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8311398/

相关文章:

Python - 我怎样才能让客户端能够多次连接?

assembly - 为什么 x86 汇编中一个字是 2 个字节而不是 4 个字节?

assembly - 如何定义一个用户定义的事件来被 PAPI 衡量?

assembly - "DS:[40207A]"在汇编中是什么意思?

x86 - 使用 gdb 计算机器指令

c++ - 黄色检测程序断言失败

regex - 从 bash 中的字符串中删除所有特殊字符和大小写

linux - 如何在 bash 中使用路径名和重新排序的序列批量重命名多个图像?

c - C 中如何返回 void* 指针?

assembly - x86 中 BND RET 的含义