Reputation: 1675
I write a little program to understand syscalls. In the following you will find creat(...) and write(...). It should be easy. So, as you maybe guess, what the program does is it creates first a file and then it fills it with a text. It should be also position independent code. Therefore, I write it using the "jump-call-pop" combination.
So, it looks like:
Section .text
global _start
_start:
jmp short GoToFileName
fileCreation:
pop esi ; address of file name
xor eax, eax ; clear eax
mov byte [esi+13], al ; terminate file name string with NULL
mov cx, 0x309 ; create file with all possible permissions
mov ebx, esi ; ebx gets address of file name
mov al, 0x8 ; al gets syscall number 8 of creat()
int 0x80 ; create the file
mov edx, eax ; write resulting file descriptor in edx
jmp short TextInput
copyProcess:
pop esi ; address of input string
xor eax, eax ; clear eax
mov byte [esi+23], al ; terminate input string with NULL
mov dl, 0x17 ; dl gets number of bytes to write
mov ecx, esi ; ecx gets address of input string
mov ebx, edx ; ebx gets file descriptor of created file
mov al, 0x4 ; al gets syscall number of write
int 0x80 ; write that input string
GoToFileName:
call fileCreation
db '/tmp/file.text'
TextInput:
call copyProcess
db 'This the output file'
When I compile it, link it and then run it...nothing happens /tmp directory. Only the file is created. But it is empty. As comparison, I write the same in C. The C code works. In the /tmp, suddenly a file.txt is created. But using the assembly code it does not work. Another point is the following: When I only take the creation part(fileCreation), then the assembly works. But when I combine it with the write part(copyProcess) then the whole does not work. Therefore, I assume that my mistake is somewhere in the copyProcess part. But I could not find it.
Can somebody help me ?
Upvotes: 0
Views: 1579
Reputation: 7228
Your code had some bugs:
0777
is hex 0x1ff
.create()
instead of open(..., O_CREAT)
you can't handle the case where the file already exists.write()
This code works:
Section .text
global _start
_start:
jmp short GoToFileName
open:
pop esi ; address of file name
mov edx, 0x1ff ; 0777
mov ecx, 0x41 ; O_CREAT | O_WRONLY
mov ebx, esi ; ebx gets address of file name
mov eax, 0x5 ; SYS_open
int 0x80
mov ebx, eax ; write resulting file descriptor in EBX
jmp short TextInput
write:
pop esi ; address of input string
mov edx, 20 ; edx gets number of bytes to write
mov ecx, esi ; ecx gets address of input string
mov eax, 0x4 ; SYS_write
int 0x80
exit:
mov ebx, 0
mov eax, 1
int 0x80
GoToFileName:
call open
db '/tmp/file.text',00
TextInput:
call write
db 'This the output file'
When I add the NULL-terminator at the end of my string, must I then count the NULL, too?
open()
takes a NULL terminated filenamewrit()
takes a byte array and a lengthopen()
. write()
doesn't care about NULL termination because it just tries to write LENGTH bytes.Upvotes: 3