assembly - Create/Write to file x86 Linux -


i have been trying teach myself 32-bit x86 (nasm). trying have user input file name, open/create file, take user's message , write message file. have gone through in gdb , syscalls returned correctly. after program runs file appears created improperly , nothing written it. ahev seen of other question similar code seems same their's can't seem figure out heck going on.

here noob code:

global _start section .data   fmsg:  db "enter filename: ", 0   .len:  equ $ - fmsg   umsg:  db "enter message: ", 0   .len:  equ $ - umsg   buff:  times 50 db 0  ;array user string   .blen: equ $ - buff   fname: times 50 db 0 ;array filename   .flen: equ $ - fname    ;modes   o_rdonly: db 0        ;read-only   o_wronly: db 1        ;wirte-only   o_rdwr:   db 2        ;read , write    ;flags   o_creat:  dw 100o     ;create file if file doesnt exists   o_trunc:  dw 1000o    ;truncate file   o_append: dw 2000o    ;append file   section .bss   fd:   resd 1          ;file descriptor   bret: resd 1          ;read buffer return value   fret: resd 1          ;read filename return value   tmp:  resd 1          ;temp 4 byte variable  section .text _start:  fprompt:               ;print prompt   mov eax, 0x4         ;syscall 4 - write()   mov ebx, 0x1         ;file desc 1 - stdout   mov ecx, fmsg        ;print message   mov edx, fmsg.len    ;length of message   int 80h              ;syscall interupt  filein:   mov eax, 0x3          ;syscall 3 - read()   mov ebx, 0x0          ;file desc 0 - stdin   mov ecx, fname        ;dst buffer   mov edx, fname.flen   ;length of buffer   int 80h               ;syscall interupt   mov [fret], eax       ;save return value file return variable   cmp eax, edx          ;read max bytes or more?   jb  fileopen          ;jmp bytes read < max   mov bl, [ecx+eax-1]   ;grab last byte @ last index before '\0'   cmp bl, 10            ;does = '\n' ?   je  clean1   inc dword [fret]      ;len++  clean1:               ;loop clear excess input, if   mov eax, 0x3        ;syscall 3 - read()   mov ebx, 0x0        ;file desc 0 - stdin   mov ecx, tmp        ;temp buffer   mov edx, 0x1        ;read 1 byte   int 80h             ;;syscall interupt   test eax, eax       ;eof?   jz  fileopen        ;yes, jump pback   mov al, [tmp]       ;put character lower 8 bits of eax   cmp al, 10          ;is = lf ?   jne clean1          ;no, jump begining of loop  fileopen:   mov eax, 0x05   mov ebx, fname      ;filename   or  ecx, o_creat    ;if doesn't exist create file   or  ecx, o_trunc    ;truncate   mov edx, o_wronly   ;write   int 80h             ;syscall interupt   mov [fd], eax       ;save file descripor  prompt2:   mov eax, 0x4         ;syscall 4 - write()   mov ebx, 0x1         ;file desc 1 - stdout   mov ecx, umsg        ;print message   mov edx, umsg.len    ;length of message   int 80h  userin:   mov eax, 0x3          ;syscall 3 - read()   mov ebx, 0x0          ;file desc 0 - stdin   mov ecx, buff         ;dst buffer   mov edx, buff.blen    ;length of buffer   int 80h               ;syscall interupt   mov [bret], eax       ;save return value buff return variable   cmp eax, edx          ;read max bytes or more?   jb  writetofile       ;jmp bytes read < max   mov bl, [ecx+eax-1]   ;grab last byte @ last index before '\0'   cmp bl, 10            ;does = '\n' ?   je  clean2   inc dword [bret]      ;len++  clean2:               ;loop clear excess input, if   mov eax, 0x3        ;syscall 3 - read()   mov ebx, 0x0        ;file desc 0 - stdin   mov ecx, tmp        ;temp buffer   mov edx, 0x1        ;read 1 byte   int 80h             ;syscall   test eax, eax       ;eof?   jz  writetofile     ;yes, jump pback   mov al, [tmp]       ;put character lower 8 bits of eax   cmp al, 10          ;is = lf ?   jne clean2          ;no, jump begining of loop   writetofile:   mov eax, 0x4         ;syscall 4 - write()   mov ebx, [fd]        ;file desc 1 - stdout   mov ecx, buff        ;print message   mov edx, [bret]      ;length of message   int 80h              ;syscall interupt  closefile:   mov eax, 0x6      ;syscall 6 - close()   mov ebx, [fd]     ;file desc   int 80h           ;syscall interupt  exit:               ;return 0   mov eax, 1        ;syscall 1 - exit()   mov ebx, 0        ;return val   int 80h           ;syscall interupt 

here example of after running it: output

the file "test.txt?" shows , shows executable though set read/write file. when try open there nothing there. thoughts? mentioned, new , teaching myself if have tips on improvement other areas of program please let me know! :)

we have multiple errors (or 1 big one) in following 3 lines of code:

or  ecx, o_creat    ;if doesn't exist create file or  ecx, o_trunc    ;truncate mov edx, o_wronly   ;write 

the problem:

what values registers ecx , edx have after these lines?

you perform 2 or operations ecx register not initialized @ moment!

this means can sure bits representing o_creat , o_trunc (whatever these values mean - see below) set don't know values other bits have.

the o_wronly bit should set in ecx, not in edx. edx should contain desired file mode instead.

unfortunately there 2 different types of assembler - don't know type nasm of:

  • one type of assembler interpret first instruction as: or ecx, [o_creat]
  • the other type interpret as: or ecx, address_of(o_creat)

in first case instruction mov edx, o_wronly read 4 bytes starting o_wronly byte edx register edx have value 0x400201 (o_creat*0x10000+o_rdwr*0x100+o_wronly).

in second case edx contain address of o_wronly rather value.

the value wrong in case.


Comments

Popular posts from this blog

ubuntu - PHP script to find files of certain extensions in a directory, returns populated array when run in browser, but empty array when run from terminal -

php - How can i create a user dashboard -

javascript - How to detect toggling of the fullscreen-toolbar in jQuery Mobile? -