Take the 2-minute tour ×

I try to implement cat>filename command in NASM in Ubuntu 11.04 using system calls. My program is compiled successfully and run successfully (seems so). But whenever I tried to fire cat filename command it shows "No such file or directory" yet I see the file residing in the directory. And if I try to open the file by double clicking it shows me "You do not have the permissions necessary to open the file." Can you please help me to find the errors in my code?

The code is following:

section .data
   msg:     dd "%d",10,0    
   msg1:    db "cat>",0
   length:  equ $-msg1
section .bss
   a    resb 100
       len1 equ $-a
   b    resd 1
   c    resb 100       
   len2 equ $-c
section .txt
  global main
  mov eax,4   ;;it will print cat>
  mov ebx,1
  mov ecx,msg1
  mov edx,length
  int 80h
  mov eax,3   ;;it will take the file name as input
  mov ebx,0
  mov ecx,a
  mov edx,len1
  int 80h

  mov eax,5   ;;it will create the file by giving owner read/write/exec permission
  mov ebx,a
  mov ecx,0100  
  mov edx,1c0h
  int 80h

  cmp eax,0
  jge inputAndWrite
  jmp errorSegment

  mov [b],eax   

  mov eax,3   ;;take the input lines
  mov ebx,0
  mov ecx,c
  mov edx,len2
  int 80h

  mov edx,eax   ;;write the input lines in the file
  mov eax,4
  mov ebx,[b]
  mov ecx,c
  int 80h   

  jmp done  
  jmp done
  mov eax, 1 
  xor ebx, ebx 
  int 80h 

p.s. The above code is re-edited by taking the suggestions from RageD. Yet,the file I have created has not contain any lines of input given from "inputAndWrite" segment. I am looking for your suggestion.

share|improve this question
Are you trying to re-implement cat (that is, concatenate files and print to STDOUT), or just create a program to copy files like cp? In either case, before testing your program with cat filename, have you checked which cat? In Debian Wheezy which cat outputs /bin/cat. –  nrz Apr 9 '13 at 22:55
@nrz: I am trying to implement : cat > file1. After firing this command file1 will contain the input lines given from command line. But after running my program file1 is created but whenevr I tried to open the file it shows "You do not have the permissions necessary to open the file." –  sabu Apr 9 '13 at 23:03
add comment

1 Answer

Your major problem with permissions is that permissions are in octal and you have listed them in decimal. You are looking for 0700 in base 8, not base 10. So instead, you can try using 1c0h (0700 octal in hexadecimal). So the following code fix should fix your permissions problem:

;; This is file creation
mov eax, 5
mov ebx, a
mov ecx, 01h ; Edited here for completeness - forgot to update this initially (see edit)
mov edx, 1c0h

For your reference, a quick guide (maybe somewhat outdated, but for the most part correct) for linux system calls is to use the Linux System Call Table. It is extremely helpful in remembering how the registers need to be set, etc.

Another critical issue is writing to the file. I think you became a little confused on a few issues. First of all, be careful with your length variables. Assembly is done "in-line," that is, when you calculate len1, you calculate the distance between a plus everything in between a to len1. That said, your length values should look like this:

.section bss
a resb 100
len1 equ $ - a
b resd 1
c resb 100
len2 equ $ - c

Doing this should make sure that you have proper reads (although it is important to note that you are restricted by your buffer sizes here for input).

Another crucial issue I found is how you're trying to write to the file. You flipped the syscall registers.

;; Write to file
mov edx, eax ;; Amount of data to write
mov eax, 4 ;; Write syscall
mov ebx, [b] ;; File descriptor to write out to (I think this is where you stored this, I don't remember exactly)
mov ecx, c ;; Buffer to write out

From here, I would make a few more adjustments. First off, to end nicely (no segfault), I would suggest simply using exit. Unless this is in another program, ret may not always work properly (particularly if this is a standalone x86 program). The code for the exit syscall is below:

;; Exit
mov eax, 1 ;; Exit is syscall 1
xor ebx, ebx ;; This is the return value
int 80h ;; Interrupt

Also, as for cleanliness, I assume you are taking input buffered by a newline. If this is the case, I would suggest stripping away the newline character after the filename. The simplest way to do this is to simply null-terminate after the last character (which will be new line). So, after reading input for the filename, I would place some code similar to this:

;; Null-terminate the last character - this assumes it directly follows the read call
;; and so the contents of eax are the amount of bytes read
mov ebx, eax ;; How many bytes read (or offset to current null-terminator)
sub ebx, 1 ;; Offset in array to the last valid character
add ebx, a ;; Add the memory address (i.e. in C this looks like a[OFFSET])
mov BYTE [ebx], 0 ;; Null-terminated

Finally, it is polite in larger projects to close your file descriptors when you're done. It may not be necessary here since you are immediately exiting, but that would look something like:

;; Close fd
mov eax, 6 ;; close() is syscall 6
mov ebx, [b] ;; File descriptor to close
int 80h


Sorry, I missed the writing issue. You are opening your file with value 100. What you want is 1 for O_RDWR (read and write capabilities). Also, you may want to consider simply using the sync system call (syscall number 0x24 with no arguments) to make sure your buffers get properly flushed; however, in my tests this was unnecessary since the line-feed to enter the data should technically do this, I believe. So the update bit of code to open the file properly should look like this:

; Open file
mov eax, 5
mov ebx, a
mov ecx, 01h
mov edx, 1c0h
int 80h

Hope this helps. Good luck!

share|improve this answer
Thank you very much RageD. You explain like I am sitting before you and like a teacher. Thank you again –  sabu Apr 10 '13 at 5:22
@nrz@RageD: After making all the changes the newly created file does not contain the input lines I have given from command line. I re-edit my code above for your consideration. –  sabu Apr 10 '13 at 5:45
@SaugataBose: I have updated my response, sorry! I missed that subtle issue. Good luck. –  RageD Apr 11 '13 at 0:10
add comment

Your Answer


