【问题标题】:How do you create a file in assembly with a dynamically specified file path?如何使用动态指定的文件路径在程序集中创建文件?
【发布时间】:2023-03-21 10:00:01
【问题描述】:

这个问题主要是如何处理任意长字符串的路径名,在汇编中,没有db 或任何类似的助手。我见过几个例子,例如this,它显示:

section .text
   global _start         ;must be declared for using gcc

_start:                  ;tell linker entry point
   ;create the file
   mov  eax, 8
   mov  ebx, file_name
   mov  ecx, 0777        ;read, write and execute by all
   int  0x80             ;call kernel

   section  .data
file_name db 'myfile.txt'

但是,我特别想了解如何动态地进行此操作。我想(1)更好地理解文件名在汇编方面的要求(是否需要空终止符等),更重要的是(2)指定文件名不使用 db 或任何汇编程序助手。例如,您可以通过命令行指定文件名,目标文件将不知道其结构。

你是怎么做到的?

【问题讨论】:

  • (1) 是的,字符串需要一个空终止符 (2) 与创建文件无关,更多的是与访问参数有关。
  • 与文件名无关,但您的文件模式错误,因为 0 前缀并不意味着 nasm 的八进制。请参阅How to represent octal numbers in Assembly? 了解正确的做法。

标签: linux assembly x86 system-calls


【解决方案1】:

采用 const char* 而没有长度 arg 的系统调用始终采用 C 字符串:0 终止,隐式长度

喜欢open(const char *path, int flags, int mode),不像write(int fd, void *buf, size_t len)

这就是为什么它们在像open("input.txt", O_RDONLY)open(argv[1], O_WRONLY|O_CREAT) 这样从C 调用时工作的原因。请记住,C 字符串文字会为您提供指向静态存储中 char 数组的指针,并带有 0 终止符。

顺便说一句,NULL 是一个指针常量。 NUL 是 ASCII '\0'。只需将它们称为“0终止”字符串即可。


是的,您应该在db 的末尾使用, 0

命令行参数始终采用这种 C 字符串格式;这是 Unix 跨系统调用/进程边界传递字符串数据的方式, 以及 ISO C 标准库函数。这包括所有路径名。


在 Linux 中,在进入 _start 时,堆栈指针指向 argc。上面是char *argv[] 数组的元素。 (不是char **argv 指针,只是堆栈上的一组值,从 ESP+4 到 ESP+argc*4。也由 NULL 指针终止(0))。这记录在 i386 和 x86-64 System V ABI 文档中。

Linux Assembly x86_64 create a file using command line parameters 显示了将argv[1] 加载到系统调用的pathname arg 中的示例。

Reading from a file in assembly 是一个 32 位示例。

【讨论】:

    【解决方案2】:

    只需以某种方式在内存中构建字符串(使用空终止符,正如 cmets 中所指出的那样),然后将指针传递给它以代替 file_name。要使用命令行参数,它已经为您构建了,所以只需指向它,如下所示:mov ebx, [esp + 8](作为参考,相当于argv[1])。顺便说一句,在实际程序中,您应该在执行此操作之前检查argc(位于[esp])以确保它至少为2。

    【讨论】:

    • 它怎么知道使用空指针,在英特尔文档中的某个地方吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-15
    • 2011-09-10
    • 2020-08-10
    相关资源
    最近更新 更多