如何使用动态指定的文件路径在程序集中创建文件?

How do you create a file in assembly with a dynamically specified file path?

这个问题主要是如何在没有 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)指定文件名 without 使用 db 或任何汇编助手。例如,您可以通过命令行指定文件名,目标文件将不知道其结构。

你是怎么做到的?

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

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

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

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

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


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

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


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

显示了将 argv[1] 加载到系统调用的 pathname arg 中的示例。

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