Reputation: 79248
This question is mainly how to handle the pathname which is an arbitrarily long string, in assembly, without db
or any helpers like that. I have seen several examples such as this which shows:
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'
However, I would specifically like to understand how to do this dynamically. I would like to (1) better understand the requirements of the filename in terms of assembly (does it need a null terminator, etc.), and more importantly (2) specify the file name without the use of db
or any assembler helpers. For example, you could specify the file name through the command line, and its structure would be unknown to the object file.
How do you do this?
Upvotes: 2
Views: 326
Reputation: 364160
System calls that take a const char*
without a length arg always take C strings: 0-terminated, implicit length.
Like open(const char *path, int flags, int mode)
, unlike write(int fd, void *buf, size_t len)
.
This is why they work when called from C like open("input.txt", O_RDONLY)
, or open(argv[1], O_WRONLY|O_CREAT)
. Remember that C string literals give you a pointer to an array of char
in static storage with a 0
terminator.
BTW, NULL is a pointer constant. NUL is ASCII '\0'
. Just call them "0
terminated" strings.
So yes, you should use , 0
at the end of your db
.
Command-line args are always in this C-string format; it's how Unix passes around string data across system-call / process boundaries, as well as to ISO C standard library functions. This includes all pathnames.
In Linux, on entry to _start
, the stack pointer points at argc
. Above that are the elements of the char *argv[]
array. (Not a char **argv
pointer, just an array of values right there on the stack, from ESP+4 to ESP+argc*4. Also terminated by a NULL pointer (0
)). This is documented in the i386 and x86-64 System V ABI docs.
Linux Assembly x86_64 create a file using command line parameters shows an example of loading argv[1]
into the pathname
arg of a system call.
Reading from a file in assembly is a 32-bit example.
Upvotes: 3
Reputation: 48572
Just build the string in memory somehow (with a null terminator, as was pointed out in the comments), and then pass the pointer to it in place of file_name
. To use a command-line argument, it's already built for you, so just point to it, like this: mov ebx, [esp + 8]
(for reference, that's equivalent to argv[1]
). By the way, in a real program, you should check argc
(which lives at [esp]
) before you do that to make sure it's at least 2.
Upvotes: 1