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:
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
Post a Comment