flat assembler
Message board for the users of flat assembler.

Index > Linux > Error calling sys_write, help please

Author
Thread Post new topic Reply to topic
Thaorius



Joined: 27 Jul 2006
Posts: 42
Thaorius 05 Aug 2006, 03:40
Hi!

I wrote a library for packing files in my own format(tpack) for windows, so i'm translating it to linux-asm.
I started it with the basic writing functions.

This is my TPacker.inc:
Code:
; TPacker v2.0 library for GNU/Linux OS 

proc tpackw.new stdcall file
        stdcall sys_creat, [file], 00644o       ; Attemp to create packet
        
        test eax,eax                            ; Test for error
        js .error                               ; Jump on error
        clc                                     ; Clear carry flag
        
        stdcall sys_write, eax, __tpack_head, __tpack_head_size
        test eax,eax                            ; Test for error
        js .error                               ; Jump on error
        
        jmp .ret                                ; Return
.error:
        stc                                     ; Set Carry Flag
        jmp .ret                                ; Return
.ret:
        ret
endp

proc tpackw.end stdcall fd
        stdcall sys_write, [fd], __tpack_end_head, __tpack_end_head_size
        test eax,eax                            ; Test for error
        js .error                               ; Jump on error
        clc
        
        jmp .ret                                ; Return
.error:
        stc                                     ; Set Carry Flag
        jmp .ret                                ; Return
.ret:
        ret
endp

__tpack_head db "tpack2.0",0
__tpack_head_size = $-__tpack_head
__tpack_end_head db "epack",0
__tpack_end_head_size = $-__tpack_end_head    


And the TPacker.asm for testing:
Code:
format ELF executable
entry main

include 'api.inc'
include 'TPacker.inc'

segment readable executable

main:
        stdcall tpackw.new, _path
        ;jc .error
        
        stdcall tpackw.end, eax
        jc .error
        
        jmp .ret
.error:
        stdcall sys_write, 1 , _error, _error_size
        jmp .ret
.ret:
        stdcall sys_exit,1
        
segment readable writable
_path db "/home/thaorius/asm/pack.tpack",0
_error db "Error!",10,0
_error_size = $-_error    


It build's fine, but on runtime, the function tpackw.end returns with error and the 'epack' head is not writed. But, if you look at tpack.new there is a call to sys_write with the fd that sys_creat returns.
The problem is that the head 'tpack2.0' is writed without problems but the 'epack' isn't.

Any ideas?

P/D: api.inc
Code:
; GNU/Linux API Wrapper
include 'macros.inc'

O_RDONLY equ 00
O_RWONLY equ 01
O_RDRW equ 02

proc sys_exit stdcall uses eax ebx,ecode
        mov eax, 1              ; Select sys_exit function
        mov ebx, [ecode]        ; Exit code
        int 80h                 ; Call the kernel
        ret                     ; Return
endp

proc sys_fork stdcall
        mov eax, 2              ; Select sys_fork function
        int 80h                 ; Call the kernel
        
        test eax, eax           ; Check for error
        js .error               ; Jump on error
        
        clc                     ; Clear carry flag
        jmp .ret                ; Jump to return instruction
.error:
        stc                     ; Set carry flag
        jmp .ret                ; Jump to return instruction
.ret:
        ret                     ; Return
endp

; TEST THIS FUNCTION, IT READS BUT RETURNS ERROR ANYWAY
proc sys_read stdcall uses eax ebx ecx edx, fd, buffer, nbytes
        mov eax, 3              ; Select sys_read function
        mov ebx, [fd]           ; File Descriptor
        mov ecx, [buffer]       ; Buffer address
        mov edx, [nbytes]       ; Bytes to read
        int 80h                 ; Call the kernel
        
        test eax,eax            ; Check for error
        js .error               ; If the sign flag is set go to error
        
        clc                     ; Clear carry flag
        jmp .ret                ; Jump to return instruction
.error:
        stc                     ; Set carry flag
        jmp .ret                ; Jump to return instruction
.ret:
        ret                     ; Return
endp

proc sys_write stdcall uses ebx ecx edx, fd, buffer, buffer_len
        mov eax, 4              ; Select sys_write function
        mov ebx, [fd]           ; File Descriptor
        mov ecx, [buffer]       ; Buffer
        mov edx, [buffer_len]   ; Buffer Len
        int 80h                 ; Call the kernel
        
        test eax,eax            ; Check for error
        js .error               ; If the sign flag is set go to error
        
        clc                     ; Clear carry flag
        jmp .ret                ; Jump to return instruction
.error:
        stc                     ; Set carry flag
        jmp .ret                ; Jump to return instruction
.ret:
        ret                     ; Return
endp

proc sys_open stdcall uses ebx ecx, road, flags
        mov eax, 5              ; Select sys_open function
        mov ebx, [road]         ; File location
        mov ecx, [flags]        ; Flags
        int 80h                 ; Call the kernel
        
        test eax,eax            ; Check the file descriptor
        js .error               ; If the sign flag is set go to error
        
        clc                     ; Clear carry flag
        jmp .ret                ; Jump to return instruction
.error:
        stc                     ; Set carry flag
        jmp .ret                ; Jump to return instruction
.ret:
        ret                     ; Return
endp

proc sys_close stdcall uses ebx, fd
        mov eax, 6              ; Select sys_close function
        mov ebx, [fd]           ; File descriptor
        int 80h                 ; Call the kernel
        
        test eax,eax            ; Check for error
        js .error               ; If the sign flag is set go to error
        
        clc                     ; Clear carry flag
        jmp .ret                ; Jump to return instruction
.error:
        stc                     ; Set carry flag
        jmp .ret                ; Jump to return instruction
.ret:
        ret                     ; Return
endp

proc sys_creat stdcall uses ebx ecx, what, mode
        mov eax, 8              ; Select sys_creat function
        mov ebx, [what]         ; File to create
        mov ecx, [mode]         ; Mode
        int 80h                 ; Call the kernel
        
        test eax,eax            ; Check the file descriptor
        js .error               ; If the sign flag is set go to error
        
        clc                     ; Clear carry flag
        jmp .ret                ; Jump to return instruction
.error:
        stc                     ; Set carry flag
        jmp .ret                ; Jump to return instruction
.ret:
        ret                     ; Return
endp

proc sys_brk stdcall uses ebx, edsegment
        mov eax, 45             ; Select sys_brk function
        lea ebx, [edsegment]    ; End data segment
        int 80h                 ; Call the kernel
        
        test eax,eax            ; Check for error
        js .error               ; If the sign flag is set go to error
        
        clc                     ; Clear carry flag
        jmp .ret                ; Jump to return instruction
.error:
        stc                     ; Set carry flag
        jmp .ret                ; Jump to return instruction
.ret:
        ret                     ; Return
endp    


Thanks for helping me.
Post 05 Aug 2006, 03:40
View user's profile Send private message Visit poster's website MSN Messenger Reply with quote
arafel



Joined: 29 Aug 2006
Posts: 131
Location: Jerusalem, Israel
arafel 29 Aug 2006, 14:11
It fails because tpackw.new doesn't return a file descriptor, but rather a sys_write return value.
Post 29 Aug 2006, 14:11
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 30 Aug 2006, 05:14
also in linux, you don't test error as return value=0, but like this:
Code:
cmp eax, -4069
ja .error    

it's like this with EVERY system call... problem is that Linux system calls are NOT documented, only their C wrappers, which ARE different. see
http://www.lxhp.in-berlin.de/lhpsyscal.html.

Even "strace" utility catches system call but displays them as if it was libc call.... stupid
Post 30 Aug 2006, 05:14
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.