Author Topic: Assembly version of perror() maybe  (Read 11675 times)

Offline TightCoderEx

  • Full Member
  • **
  • Posts: 103
Assembly version of perror() maybe
« on: May 10, 2012, 10:16:35 PM »
Here is a simple method by which to get error number and error text

Code: [Select]
; =========================================================================================================
; Display ASCII string on console (monitor)

; ENTRY: RAX = Error code

; LEAVE: RAX = Negated error code
; RSI = Pointer to null terminated string describing error condition     

;          Strings BBE = 3006 Bytes : Pointers 410 = 1040 Bytes : Proc 1F = 31 Bytes
; ---------------------------------------------------------------------------------------------------------

 Get_Err_Pntr: mov rsi, PNTRS ; Get pointer to array of error pointers
  neg rax
  push rax ; We want to return this value to caller
  dec rax ; Zero index
 
  ; I may decide to live on the wild side and change PNTRS to dwords. That will save 512 bytes
  ; but could really screw up a linker that would put .const section outside dword address space
 
  shl rax, 3 ; RAX *= 8;
  add rsi, rax ; Point to its position in PNTRS
  lodsq
 
  ; This is peculuar to my applications as the routine that display's text requires pointer in RSI
 
  mov rsi, rax
  pop rax ; Return negated error code to caller.
 
  ret

I may at sometime work on a decorated version of the same thing that will point to a string that looks like
        Error: [ ### ] -- Operation cancelled
 for instance

Pointers
Code: [Select]
    PNTRS
                dq    EPERM, ENOENT, ESRCH, EINTR, EIO, ENXIO, E2BIG, ENOEXEC, EBADF, ECHILD, EAGAIN
dq    ENOMEM, EACCES, EFAULT, ENOTBLK, EBUSY, EEXIST, EXDEV, ENODEV, ENOTDIR, EISDIR
dq    EINVAL,ENFILE, EMFILE, ENOTTY, ETXTBSY, EFBIG, ENOSPC, ESPIPE, EROFS, EMLINK
dq    EPIPE, EDOM, ERANGE, EDEADLK, ENAMETOOLONG, ENOSYS, ENOTEMPTY, ELOOP, EWOULDBLOCK
dq    ENOMSG, EIDRM, ECHRNG, EL2NSYNC, EL3HLT, EL3RST, ELNRNG, EUNATCH, ENOCSI, EL2HLT
dq    EBADE, EBADR, EXFULL, ENOANO, EBADRQC, EBADSLT, EDEADLOCK, EBFONT, ENOSTR, ENODATA
dq    ETIME, ENOSR, ENONET, ENOPKG, EREMOTE, ENOLINK, EADV, ESRMNT, ECOMM , EPROTO
dq    EMULTIHOP, EDOTDOT, EBADMSG, EOVERFLOW, ENOTUNIQ, EBADFD, EREMCHG, ELIBACC, ELIBBAD
dq    ELIBSCN, ELIBMAX, ELIBEXEC, EILSEQ, ERESTART, ESTRPIPE, EUSERS, ENOTSOCK
dq    EDESTADDRREQ, EMSGSIZE, EPROTOTYPE, ENOPROTOOPT, EPROTONOSUPPORT, ESOCKTNOSUPPORT
dq    EOPNOTSUPP, EPFNOSUPPORT, EAFNOSUPPORT, EADDRINUSE, EADDRNOTAVAIL, ENETDOWN
dq    ENETUNREACH, ENETRESET, ECONNABORTED, ECONNRESET, ENOBUFS, EISCONN, ENOTCONN
dq    ESHUTDOWN, ETOOMANYREFS, ETIMEDOUT, ECONNREFUSED, EHOSTDOWN, EHOSTUNREACH, EALREADY
dq    EINPROGRESS, ESTALE, EUCLEAN, ENOTNAM, ENAVAIL, EISNAM, EREMOTEIO, EDQUOT
dq    ENOMEDIUM, EMEDIUMTYPE, ECANCELED, ENOKEY, EKEYEXPIRED, EKEYREVOKED, EKEYREJECTED
dq    EOWNERDEAD, ENOTRECOVERABLE

Strings (ASCII)
Code: [Select]
    EPERM db    'Operation not permitted', 0
    ENOENT db    'No such file or directory', 0
    ESRCH db    'No such process', 0
    EINTR db    'Interrupted system call', 0
    EIO db    'I/O error', 0
    ENXIO db    'No such device or address', 0
    E2BIG db    'Argument list too long', 0
    ENOEXEC db    'Exec format error', 0
    EBADF db    'Bad file number', 0
    ECHILD db    'No child processes', 0
    EAGAIN db    'Try again', 0
    ENOMEM db    'Out of memory', 0
    EACCES db    'Permission denied', 0
    EFAULT db    'Bad address', 0
    ENOTBLK db    'Block device required', 0
    EBUSY db    'Device or resource busy', 0
    EEXIST db    'File exists', 0
    EXDEV db    'Cross-device link', 0
    ENODEV db    'No such device', 0
    ENOTDIR db    'Not a directory', 0
    EISDIR db    'Is a directory', 0
    EINVAL db    'Invalid argument', 0
    ENFILE db    'File table overflow', 0
    EMFILE db    'Too many open files', 0
    ENOTTY db    'Not a typewriter', 0
    ETXTBSY db    'Text file busy', 0
    EFBIG db    'File too large', 0
    ENOSPC db    'No space left on device', 0
    ESPIPE db    'Illegal seek', 0
    EROFS db    'Read-only file system', 0
    EMLINK db    'Too many links', 0
    EPIPE db    'Broken pipe', 0
    EDOM db    'Math argument out of domain of func', 0
    ERANGE db    'Math result not representable', 0
    EDEADLK db    'Resource deadlock would occur', 0
    ENAMETOOLONG db    'File name too long', 0
    ENOLCK db    'No record locks available', 0
    ENOSYS db    'Function not implemented', 0
    ENOTEMPTY db    'Directory not empty', 0
    ELOOP db    'Too many symbolic links encountered', 0
    EWOULDBLOCK db    'Operation would block', 0
    ENOMSG db    'No message of desired type', 0
    EIDRM db    'Identifier removed', 0
    ECHRNG db    'Channel number out of range', 0
    EL2NSYNC db    'Level 2 not synchronized', 0
    EL3HLT db    'Level 3 halted', 0
    EL3RST db    'Level 3 reset', 0
    ELNRNG db    'Link number out of range', 0
    EUNATCH db    'Protocol driver not attached', 0
    ENOCSI db    'No CSI structure available', 0
    EL2HLT db    'Level 2 halted', 0
    EBADE db    'Invalid exchange', 0
    EBADR db    'Invalid request descriptor', 0
    EXFULL db    'Exchange full', 0
    ENOANO db    'No anode', 0
    EBADRQC db    'Invalid request code', 0
    EBADSLT db    'Invalid slot', 0
    EDEADLOCK db    0 ; = EDEADLK
    EBFONT db    'Bad font file format', 0
    ENOSTR db    'Device not a stream', 0
    ENODATA db    'No data available', 0
    ETIME db    'Timer expired', 0
    ENOSR db    'Out of streams resources', 0
    ENONET db    'Machine is not on the network', 0
    ENOPKG db    'Package not installed', 0
    EREMOTE db    'Object is remote', 0
    ENOLINK db    'Link has been severed', 0
    EADV db    'Advertise error', 0
    ESRMNT db    'Srmount error', 0
    ECOMM db    'Communication error on send', 0
    EPROTO db    'Protocol error', 0
    EMULTIHOP db    'Multihop attempted', 0
    EDOTDOT db    'RFS specific error', 0
    EBADMSG db    'Not a data message', 0
    EOVERFLOW db    'Value too large for defined data type', 0
    ENOTUNIQ db    'Name not unique on network', 0
    EBADFD db    'File descriptor in bad state', 0
    EREMCHG db    'Remote address changed', 0
    ELIBACC db    'Can not access a needed shared library', 0
    ELIBBAD db    'Accessing a corrupted shared library', 0
    ELIBSCN db    '.lib section in a.out corrupted', 0
    ELIBMAX db    'Attempting to link in too many shared libraries', 0
    ELIBEXEC db    'Cannot exec a shared library directly', 0
    EILSEQ db    'Illegal byte sequence', 0
    ERESTART db    'Interrupted system call should be restarted', 0
    ESTRPIPE db    'Streams pipe error', 0
    EUSERS db    'Too many users', 0
    ENOTSOCK db    'Socket operation on non-socket', 0
    EDESTADDRREQ db    'Destination address required', 0
    EMSGSIZE db    'Message too long', 0
    EPROTOTYPE db    'Protocol wrong type for socket', 0
    ENOPROTOOPT db    'Protocol not available', 0
    EPROTONOSUPPORT db    'Protocol not supported', 0
    ESOCKTNOSUPPORT db    'Socket type not supported', 0
    EOPNOTSUPP db    'Operation not supported on transport endpoint', 0
    EPFNOSUPPORT db    'Protocol family not supported', 0
    EAFNOSUPPORT db    'Address family not supported by protocol', 0
    EADDRINUSE db    'Address already in use', 0
    EADDRNOTAVAIL db    'Cannot assign requested address', 0
    ENETDOWN db    'Network is down', 0
    ENETUNREACH db    'Network is unreachable', 0
    ENETRESET db    'Network dropped connection because of reset', 0
    ECONNABORTED db    'Software caused connection abort', 0
    ECONNRESET db    'Connection reset by peer', 0
    ENOBUFS db    'No buffer space available', 0
    EISCONN db    'Transport endpoint is already connected', 0
    ENOTCONN db    'Transport endpoint is not connected', 0
    ESHUTDOWN db    'Cannot send after transport endpoint shutdown', 0
    ETOOMANYREFS db    'Too many references: cannot splice', 0
    ETIMEDOUT db    'Connection timed out', 0
    ECONNREFUSED db    'Connection refused', 0
    EHOSTDOWN db    'Host is down', 0
    EHOSTUNREACH db    'No route to host', 0
    EALREADY db    'Operation already in progress', 0
    EINPROGRESS db    'Operation now in progress', 0
    ESTALE db    'Stale NFS file handle', 0
    EUCLEAN db    'Structure needs cleaning', 0
    ENOTNAM db    'Not a XENIX named type file', 0
    ENAVAIL db    'No XENIX semaphores available', 0
    EISNAM db    'Is a named type file', 0
    EREMOTEIO db    'Remote I/O error', 0
    EDQUOT db    'Quota exceeded', 0
    ENOMEDIUM db    'No medium found', 0
    EMEDIUMTYPE db    'Wrong medium type', 0
    ECANCELED db    'Operation Canceled', 0
    ENOKEY db    'Required key not available', 0
    EKEYEXPIRED db    'Key has expired', 0
    EKEYREVOKED db    'Key has been revoked', 0
    EKEYREJECTED db    'Key was rejected by service', 0
    EOWNERDEAD db    'Owner died', 0
    ENOTRECOVERABLE db    'State not recoverable', 0

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Assembly version of perror() maybe
« Reply #1 on: May 12, 2012, 06:22:08 PM »
This is what I've got on hand for a 32-bit version. Writes to stdout - probably should write to stderr... and other potential improvements... It is what it is.

Best,
Frank

Code: [Select]
; nasm -f elf32 rpterror.asm
global report_error

%define NL 10

;---------------   
report_error:
    push eax
    push ebx
    push ecx
    push edx
   
    neg eax
    mov ecx, [error_table + eax * 4]
    xor edx, edx
.getlen:
    cmp byte [ecx + edx], 0
    jz .gotlen
    inc edx
    jmp .getlen
.gotlen:
    mov ebx, 1 ; stdout
    mov eax, 4 ; write
    int 80h
   
    pop edx
    pop ecx
    pop ebx   
    pop eax
    ret
;--------------

section .data

msg_EPERM db "EPERM - Operation not permitted ", NL, 0
msg_ENOENT db "ENOENT - No such file or directory ", NL, 0
msg_ESRCH db "ESRCH - No such process ", NL, 0
msg_EINTR db "EINTR - Interrupted system call ", NL, 0
msg_EIO db "EIO - I/O error ", NL, 0
msg_ENXIO db "ENXIO - No such device or address ", NL, 0
msg_E2BIG db "E2BIG - Argument list too long ", NL, 0
msg_ENOEXEC db "ENOEXEC - Exec format error ", NL, 0
msg_EBADF db "EBADF - Bad file number ", NL, 0
msg_ECHILD db "ECHILD - No child processes ", NL, 0
msg_EAGAIN db "EAGAIN - Try again, or EWOULDBLOCK - Operation would block ", NL, 0
msg_ENOMEM db "ENOMEM - Out of memory ", NL, 0
msg_EACCES db "EACCES - Permission denied ", NL, 0
msg_EFAULT db "EFAULT - Bad address ", NL, 0
msg_ENOTBLK db "ENOTBLK - Block device required ", NL, 0
msg_EBUSY db "EBUSY - Device or resource busy ", NL, 0
msg_EEXIST db "EEXIST - File exists ", NL, 0
msg_EXDEV db "EXDEV - Cross-device link ", NL, 0
msg_ENODEV db "ENODEV - No such device ", NL, 0
msg_ENOTDIR db "ENOTDIR - Not a directory ", NL, 0
msg_EISDIR db "EISDIR - Is a directory ", NL, 0
msg_EINVAL db "EINVAL - Invalid argument ", NL, 0
msg_ENFILE db "ENFILE - File table overflow ", NL, 0
msg_EMFILE db "EMFILE - Too many open files ", NL, 0
msg_ENOTTY db "ENOTTY - Not a typewriter ", NL, 0
msg_ETXTBSY db "ETXTBSY - Text file busy ", NL, 0
msg_EFBIG db "EFBIG - File too large ", NL, 0
msg_ENOSPC db "ENOSPC - No space left on device ", NL, 0
msg_ESPIPE db "ESPIPE - Illegal seek ", NL, 0
msg_EROFS db "EROFS - Read-only file system ", NL, 0
msg_EMLINK db "EMLINK - Too many links ", NL, 0
msg_EPIPE db "EPIPE - Broken pipe ", NL, 0
msg_EDOM db "EDOM - Math argument out of domain of func ", NL, 0
msg_ERANGE db "ERANGE - Math result not representable ", NL, 0
msg_EDEADLK db "EDEADLK - Resource deadlock would occur ", NL, 0
msg_ENAMETOOLONG db "ENAMETOOLONG - File name too long ", NL, 0
msg_ENOLCK db "ENOLCK - No record locks available ", NL, 0
msg_ENOSYS db "ENOSYS - Function not implemented ", NL, 0
msg_ENOTEMPTY db "ENOTEMPTY - Directory not empty ", NL, 0
msg_ELOOP db "ELOOP - Too many symbolic links encountered ", NL, 0
msg_EWOULDBLOCK db "EWOULDBLOCK Operation would block ", NL, 0
msg_ENOMSG db "ENOMSG - No message of desired type ", NL, 0
msg_EIDRM db "EIDRM - Identifier removed ", NL, 0
msg_ECHRNG db "ECHRNG - Channel number out of range ", NL, 0
msg_EL2NSYNC db "EL2NSYNC - Level 2 not synchronized ", NL, 0
msg_EL3HLT db "EL3HLT - Level 3 halted ", NL, 0
msg_EL3RST db "EL3RST - Level 3 reset ", NL, 0
msg_ELNRNG db "ELNRNG - Link number out of range ", NL, 0
msg_EUNATCH db "EUNATCH - Protocol driver not attached ", NL, 0
msg_ENOCSI db "ENOCSI - No CSI structure available ", NL, 0
msg_EL2HLT db "EL2HLT - Level 2 halted ", NL, 0
msg_EBADE db "EBADE - Invalid exchange ", NL, 0
msg_EBADR db "EBADR - Invalid request descriptor ", NL, 0
msg_EXFULL db "EXFULL - Exchange full ", NL, 0
msg_ENOANO db "ENOANO - No anode ", NL, 0
msg_EBADRQC db "EBADRQC - Invalid request code ", NL, 0
msg_EBADSLT db "EBADSLT - Invalid slot ", NL, 0
msg_EDEADLOCK db "EDEADLOCK - EDEADLK"
msg_EBFONT db "EBFONT - Bad font file format ", NL, 0
msg_ENOSTR db "ENOSTR - Device not a stream ", NL, 0
msg_ENODATA db "ENODATA - No data available ", NL, 0
msg_ETIME db "ETIME - Timer expired ", NL, 0
msg_ENOSR db "ENOSR - Out of streams resources ", NL, 0
msg_ENONET db "ENONET - Machine is not on the network ", NL, 0
msg_ENOPKG db "ENOPKG - Package not installed ", NL, 0
msg_EREMOTE db "EREMOTE - Object is remote ", NL, 0
msg_ENOLINK db "ENOLINK - Link has been severed ", NL, 0
msg_EADV db "EADV - Advertise error ", NL, 0
msg_ESRMNT db "ESRMNT - Srmount error ", NL, 0
msg_ECOMM db "ECOMM - Communication error on send ", NL, 0
msg_EPROTO db "EPROTO - Protocol error ", NL, 0
msg_EMULTIHOP db "EMULTIHOP - Multihop attempted ", NL, 0
msg_EDOTDOT db "EDOTDOT - RFS specific error ", NL, 0
msg_EBADMSG db "EBADMSG - Not a data message ", NL, 0
msg_EOVERFLOW db "EOVERFLOW - Value too large for defined data type ", NL, 0
msg_ENOTUNIQ db "ENOTUNIQ - Name not unique on network ", NL, 0
msg_EBADFD db "EBADFD - File descriptor in bad state ", NL, 0
msg_EREMCHG db "EREMCHG - Remote address changed ", NL, 0
msg_ELIBACC db "ELIBACC - Can not access a needed shared library ", NL, 0
msg_ELIBBAD db "ELIBBAD - Accessing a corrupted shared library ", NL, 0
msg_ELIBSCN db "ELIBSCN - .lib section in a.out corrupted ", NL, 0
msg_ELIBMAX db "ELIBMAX - Attempting to link in too many shared libraries ", NL, 0
msg_ELIBEXEC db "ELIBEXEC - Cannot exec a shared library directly ", NL, 0
msg_EILSEQ db "EILSEQ - Illegal byte sequence ", NL, 0
msg_ERESTART db "ERESTART - Interrupted system call should be restarted ", NL, 0
msg_ESTRPIPE db "ESTRPIPE - Streams pipe error ", NL, 0
msg_EUSERS db "EUSERS - Too many users ", NL, 0
msg_ENOTSOCK db "ENOTSOCK - Socket operation on non-socket ", NL, 0
msg_EDESTADDRREQ db "EDESTADDRREQ - Destination address required ", NL, 0
msg_EMSGSIZE db "EMSGSIZE - Message too long ", NL, 0
msg_EPROTOTYPE db "EPROTOTYPE - Protocol wrong type for socket ", NL, 0
msg_ENOPROTOOPT db "ENOPROTOOPT - Protocol not available ", NL, 0
msg_EPROTONOSUPPORT db "EPROTONOSUPPORT - Protocol not supported ", NL, 0
msg_ESOCKTNOSUPPORT db "ESOCKTNOSUPPORT - Socket type not supported ", NL, 0
msg_EOPNOTSUPP db "EOPNOTSUPP - Operation not supported on transport endpoint ", NL, 0
msg_EPFNOSUPPORT db "EPFNOSUPPORT - Protocol family not supported ", NL, 0
msg_EAFNOSUPPORT db "EAFNOSUPPORT - Address family not supported by protocol ", NL, 0
msg_EADDRINUSE db "EADDRINUSE - Address already in use ", NL, 0
msg_EADDRNOTAVAIL db "EADDRNOTAVAIL - Cannot assign requested address ", NL, 0
msg_ENETDOWN db "ENETDOWN - Network is down ", NL, 0
msg_ENETUNREACH db "ENETUNREACH - Network is unreachable ", NL, 0
msg_ENETRESET db "ENETRESET - Network dropped connection because of reset ", NL, 0
msg_ECONNABORTED db "ECONNABORTED - Software caused connection abort ", NL, 0
msg_ECONNRESET db "ECONNRESET - Connection reset by peer ", NL, 0
msg_ENOBUFS db "ENOBUFS - No buffer space available ", NL, 0
msg_EISCONN db "EISCONN - Transport endpoint is already connected ", NL, 0
msg_ENOTCONN db "ENOTCONN - Transport endpoint is not connected ", NL, 0
msg_ESHUTDOWN db "ESHUTDOWN - Cannot send after transport endpoint shutdown ", NL, 0
msg_ETOOMANYREFS db "ETOOMANYREFS - Too many references: cannot splice ", NL, 0
msg_ETIMEDOUT db "ETIMEDOUT - Connection timed out ", NL, 0
msg_ECONNREFUSED db "ECONNREFUSED - Connection refused ", NL, 0
msg_EHOSTDOWN db "EHOSTDOWN - Host is down ", NL, 0
msg_EHOSTUNREACH db "EHOSTUNREACH - No route to host ", NL, 0
msg_EALREADY db "EALREADY - Operation already in progress ", NL, 0
msg_EINPROGRESS db "EINPROGRESS - Operation now in progress ", NL, 0
msg_ESTALE db "ESTALE - Stale NFS file handle ", NL, 0
msg_EUCLEAN db "EUCLEAN - Structure needs cleaning ", NL, 0
msg_ENOTNAM db "ENOTNAM - Not a XENIX named type file ", NL, 0
msg_ENAVAIL db "ENAVAIL - No XENIX semaphores available ", NL, 0
msg_EISNAM db "EISNAM - Is a named type file ", NL, 0
msg_EREMOTEIO db "EREMOTEIO - Remote I/O error ", NL, 0
msg_EDQUOT db "EDQUOT - Quota exceeded ", NL, 0
msg_ENOMEDIUM db "ENOMEDIUM - No medium found ", NL, 0
msg_EMEDIUMTYPE db "EMEDIUMTYPE - Wrong medium type ", NL, 0
msg_WTF db 'WTF???', NL, 0

MAX_ERROR equ 124

error_table:
    dd msg_WTF
    dd msg_EPERM , msg_ENOENT , msg_ESRCH , msg_EINTR
    dd msg_EIO , msg_ENXIO , msg_E2BIG , msg_ENOEXEC
    dd msg_EBADF , msg_ECHILD , msg_EAGAIN , msg_ENOMEM
    dd msg_EACCES , msg_EFAULT , msg_ENOTBLK , msg_EBUSY
    dd msg_EEXIST , msg_EXDEV , msg_ENODEV , msg_ENOTDIR
    dd msg_EISDIR , msg_EINVAL , msg_ENFILE , msg_EMFILE
    dd msg_ENOTTY , msg_ETXTBSY , msg_EFBIG , msg_ENOSPC
    dd msg_ESPIPE , msg_EROFS , msg_EMLINK , msg_EPIPE
    dd msg_EDOM , msg_ERANGE , msg_EDEADLK , msg_ENAMETOOLONG
    dd msg_ENOLCK , msg_ENOSYS , msg_ENOTEMPTY , msg_ELOOP
    dd msg_EWOULDBLOCK , msg_ENOMSG , msg_EIDRM , msg_ECHRNG
    dd msg_EL2NSYNC , msg_EL3HLT , msg_EL3RST , msg_ELNRNG
    dd msg_EUNATCH , msg_ENOCSI , msg_EL2HLT , msg_EBADE
    dd msg_EBADR , msg_EXFULL , msg_ENOANO , msg_EBADRQC
    dd msg_EBADSLT , msg_EDEADLOCK , msg_EBFONT , msg_ENOSTR
    dd msg_ENODATA , msg_ETIME , msg_ENOSR , msg_ENONET
    dd msg_ENOPKG , msg_EREMOTE , msg_ENOLINK , msg_EADV
    dd msg_ESRMNT , msg_ECOMM , msg_EPROTO , msg_EMULTIHOP
    dd msg_EDOTDOT , msg_EBADMSG , msg_EOVERFLOW , msg_ENOTUNIQ
    dd msg_EBADFD , msg_EREMCHG , msg_ELIBACC , msg_ELIBBAD
    dd msg_ELIBSCN , msg_ELIBMAX , msg_ELIBEXEC , msg_EILSEQ
    dd msg_ERESTART , msg_ESTRPIPE , msg_EUSERS , msg_ENOTSOCK
    dd msg_EDESTADDRREQ , msg_EMSGSIZE , msg_EPROTOTYPE
    dd msg_ENOPROTOOPT , msg_EPROTONOSUPPORT , msg_ESOCKTNOSUPPORT
    dd msg_EOPNOTSUPP , msg_EPFNOSUPPORT , msg_EAFNOSUPPORT
    dd msg_EADDRINUSE , msg_EADDRNOTAVAIL , msg_ENETDOWN
    dd msg_ENETUNREACH , msg_ENETRESET , msg_ECONNABORTED
    dd msg_ECONNRESET , msg_ENOBUFS , msg_EISCONN , msg_ENOTCONN
    dd msg_ESHUTDOWN , msg_ETOOMANYREFS , msg_ETIMEDOUT
    dd msg_ECONNREFUSED , msg_EHOSTDOWN , msg_EHOSTUNREACH
    dd msg_EALREADY , msg_EINPROGRESS , msg_ESTALE , msg_EUCLEAN
    dd msg_ENOTNAM , msg_ENAVAIL , msg_EISNAM , msg_EREMOTEIO
    dd msg_EDQUOT , msg_ENOMEDIUM , msg_EMEDIUMTYPE

   

Offline TightCoderEx

  • Full Member
  • **
  • Posts: 103
Re: Assembly version of perror() maybe
« Reply #2 on: May 12, 2012, 07:04:21 PM »
Good point about stderr and my next version is going to have something a little more elaborate like

Error [ ### ] @ 400138 -- Out of memory

It will operate something similar to format in windows, but not near as complicated.

Offline munair

  • Jr. Member
  • *
  • Posts: 37
  • Country: nl
  • SharpBASIC compiler developer
    • SharpBASIC
Re: Assembly version of perror() maybe
« Reply #3 on: July 20, 2023, 08:08:35 AM »
Am I correct in assuming that an error code returned in rax/eax is negated and multiplied to arrive at the actual error? For example, if I try to open a file that doesn't exist then -1 is returned. So what happens is per Frank's code:
Code: [Select]
neg eax
mov ecx, [error_table + eax * 4]
the result will be 4 pointing at the second message.

Correct me if I'm wrong.
SharpBASIC (www.sharpbasic.com) is a compiler in development that uses NASM as backend.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Assembly version of perror() maybe
« Reply #4 on: July 20, 2023, 08:35:02 AM »
That sounds right, Don't think it expects rax. It's quite old.

Best,
Frank


Offline fredericopissarra

  • Full Member
  • **
  • Posts: 368
  • Country: br
Re: Assembly version of perror() maybe
« Reply #5 on: July 20, 2023, 12:15:36 PM »
Let me ask you: Why emulate strerror and/or perror?

errno is a thread local object managed by the runtime c library and not affected by syscalls, i.e, functions of the library change errno. Unless you are creating your own library, this errno emulation is useless.

And if you are suppose to use those routines in a C program they are already available via libc.

Notice that names as EPERM are integer constants (not the label for a string). And the error code is an int, a 32 bits integer value, more than enough to accomodate any possible error. Using RAX for this is too much.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Assembly version of perror() maybe
« Reply #6 on: July 20, 2023, 01:39:33 PM »
 may be wrong, Fred, but I don't think you are correct. There is no library involved here. The error number in question is returned by int 80h. I do not believe it is a "thread local object". I don't think Linux had 'em at the time I wrote this.  I have created the number to string list from errno.h.

Why? As I recall, someone asked me how I would do it.

I know you like C. I don't. One of our differences of opinion I doubt if will be resolved.  :)

Unfortunately, the original is on an IDE drive which my accursed new computer won't mount, so the above may be the only available copy. I know that the world changes whether I like it or not. I don't.

I don't like to disagree with you, Fred. I know you know a lot. But in this case I do. :)

Best,
Frank


Offline munair

  • Jr. Member
  • *
  • Posts: 37
  • Country: nl
  • SharpBASIC compiler developer
    • SharpBASIC
Re: Assembly version of perror() maybe
« Reply #7 on: July 20, 2023, 01:46:47 PM »
Let me ask you: Why emulate strerror and/or perror?
It's not emulating if used for a compiler that doesn't (want to) rely on C libs.
SharpBASIC (www.sharpbasic.com) is a compiler in development that uses NASM as backend.

Offline fredericopissarra

  • Full Member
  • **
  • Posts: 368
  • Country: br
Re: Assembly version of perror() maybe
« Reply #8 on: July 20, 2023, 03:26:00 PM »
may be wrong, Fred, but I don't think you are correct. There is no library involved here. The error number in question is returned by int 80h.
In which service? Take sys_open as example. The behavior is the same as the wrapper:
Code: [Select]
int open( const char *, int, int );Except the function returns the file descriptor or -1 if an error occurs. SysV ABI tells us if this value is negative then is mapped to -errno constant, for LINUX kernel only. This is implementation dependent (maybe won't work for other platforms like BSD, Solaris, HP-UX, etc...).

« Last Edit: July 20, 2023, 03:38:54 PM by fredericopissarra »

Offline fredericopissarra

  • Full Member
  • **
  • Posts: 368
  • Country: br
Re: Assembly version of perror() maybe
« Reply #9 on: July 20, 2023, 03:54:25 PM »
I know you like C. I don't. One of our differences of opinion I doubt if will be resolved.  :)

What's not to like?! hehehe... here, how people usually implement something like this in nasm?
Code: [Select]
void fillqw( char *p, char ch )
{
  for ( int i = 0; i < 8; i++)
    p[i] = ch;
}
Seems likely:
Code: [Select]
; Input: RDI = p, SIL = ch
fillqw:
  mov  ecx,8
.loop:
  mov  [rdi + rcx - 1],sil
  dec  ecx
  jnz  .loop
  ret
Or, maybe:
Code: [Select]
fillqw:
  mov al,sil
  mov ecx,8
  rep stosb
  ret
Here's how GCC do it:
Code: [Select]
; GCC uses SWAR!!!
; No loops and takes only 5~7 cycles (call/ret excluded).
; It can be faster than the previous code.
fillqw:
  mov   rax,0x0101010101010101  ; 1 cycle
  movzx esi,sil

  imul  rax,rsi    ; 3~4 cycles
  mov   [rdi],rax  ; 1~2 cycles
  ret
I think of C as a high level optimized assembly...
« Last Edit: July 20, 2023, 04:03:44 PM by fredericopissarra »

Offline munair

  • Jr. Member
  • *
  • Posts: 37
  • Country: nl
  • SharpBASIC compiler developer
    • SharpBASIC
Re: Assembly version of perror() maybe
« Reply #10 on: July 20, 2023, 04:31:58 PM »
I know you like C. I don't. One of our differences of opinion I doubt if will be resolved.  :)

What's not to like?! hehehe...

There can be plenty of reasons not to like C. Most importantly, it can be hard to debug. Just take the switch statement for example. Implicit fall-through is really a language design error IMO. It should be explicit (SharpBASIC actually provides that). :D

Then there is the syntax itself. Generally, I avoid any language using braces as block delimiters; the fact alone that it requires a shift key to get them (on all US keyboards) becomes tiresome and annoying when doing hours long coding.
Quote
I think of C as a high level optimized assembly...

It is the main reason why programmers would choose C. But this is only because C compilers generate among the tightest code on the planet. There's no reason why other languages wouldn't be able to do the same (if enough time and effort would be taken). Let's not forget that the first Mac OS in the 1980s was coded in Pascal, before it was surpassed by C as popular language -- largely thanks to UNIX.
« Last Edit: July 20, 2023, 04:36:28 PM by munair »
SharpBASIC (www.sharpbasic.com) is a compiler in development that uses NASM as backend.

Offline fredericopissarra

  • Full Member
  • **
  • Posts: 368
  • Country: br
Re: Assembly version of perror() maybe
« Reply #11 on: July 20, 2023, 05:21:12 PM »
There can be plenty of reasons not to like C. Most importantly, it can be hard to debug.
Surely isn't harder than debugging assembly programs!

Let's not forget that the first Mac OS in the 1980s was coded in Pascal, before it was surpassed by C as popular language -- largely thanks to UNIX.
There's a small confusion here. The first Mac OS (OS/2 and Windows too, by the way) used pascal calling convention. They weren't encoded in pascal per se. Until now Microsoft keep something like pascal calling convention on Windows (stdcall is like pascal, except on argument ordering -- which follows C's right to left pushing [in i386 mode, for example] -- the stack is cleaned by the called function, not the caller).

One of few softwares I know was entirely developed in Pascal was the first version of Photoshop.

Offline munair

  • Jr. Member
  • *
  • Posts: 37
  • Country: nl
  • SharpBASIC compiler developer
    • SharpBASIC
Re: Assembly version of perror() maybe
« Reply #12 on: July 20, 2023, 05:58:23 PM »
There's a small confusion here. The first Mac OS (OS/2 and Windows too, by the way) used pascal calling convention. They weren't encoded in pascal per se.

I must correct you there. The original operating system for the Macintosh in the early 1980s was first written in Pascal (I have seen the source code). It was only after system resources became limited that part of the code was ported to 68K assembly. You can read about it here.
« Last Edit: July 20, 2023, 06:02:44 PM by munair »
SharpBASIC (www.sharpbasic.com) is a compiler in development that uses NASM as backend.

Offline Frank Kotler

  • NASM Developer
  • Hero Member
  • *****
  • Posts: 2667
  • Country: us
Re: Assembly version of perror() maybe
« Reply #13 on: July 20, 2023, 08:11:46 PM »
Hi Fred,

Let me repeat  what I said of my code in the  first place:
"it is what it is"

Certainly it is for Linux only. Assembly is not portable.. That's one you and I agree on! Perhaps that's a good place to stop. :)

Best,
Frank