NASM - The Netwide Assembler
NASM Forum => Using NASM => Topic started by: nobody on February 29, 2008, 01:29:19 PM
-
how is it possible to use gcc linker instead of ld in order to have the error message corresponding to ERRNO printed after a int 80h call?
(i.e. be able to use the perror() function)
when i include in a C code, it doesn't seem to make the file bigger, but in asm i didn't find a way to do something similar
in put in my code
%include 'errno.inc'
and a function looking like this:
Errno:
neg eax ; eax is signed after call failure
dec eax
imul eax, 32 ; "imul", signed multiplication, because i couldn't get "mul" to work :)
; 32 because i did 32-bytes message strings
lea dword esi, [errno_table + eax]
call WriteMsg ; prints a zero-terminated string
ret
with the include file looking like this:
errno_table db 'Operation not permitted ', 10, 0 ; EPERM
db 'No such file or directory ', 10, 0 ; ENOENT
[etc...]
but, this does make my file grow in size, because it's not %define 's or anything, as i understand
AC
-
> how is it possible to use gcc linker instead of ld in order to have the error
> message corresponding to ERRNO printed after a int 80h call?
> (i.e. be able to use the perror() function)
Damned if I know, AC. I've tried this:
global main
extern perror
section .text
main:
xor ecx, ecx
mov ebx, nsf
mov eax, 5
int 80h
cmp eax, -4096
jc exit
; neg eax
; push eax
call perror
; add esp, 4
exit:
mov eax, 1
int 80h
section .data
nsf db "nothere.xyz", 0
Compiles quietly, now how do I *use* perror??? Take a parameter? Void? (must know about "errno"?) With the "push eax" in, it segfaults. Without it, it prints some garbage, followed by the word "Success" (!!!). I take this as a good sign, but I can't get it to print a message. We may need to call "write()" instead of the int 80h interface to make this work(?). Someone who knows more C can fool with it - I'm gonna quit while I'm ahead. :)
> when i include in a C code, it doesn't seem to make the file bigger,
> but in asm i didn't find a way to do something similar
When you link in more functions, they're in a shared library, so don't add much to the preexisting bloat. We could put our "asm_perror" in a shared library, too, but that's trickier. Not much point, since we'll probably be the only ones using it. (the solution to this is to run more asm programs!)
> in put in my code
> %include 'errno.inc'
>
> and a function looking like this:
> Errno:
> neg eax ; eax is signed after call failure
> dec eax
> imul eax, 32 ; "imul", signed multiplication, because i couldn't get "mul"
> to work :)
shl eax, 5 ?
> ; 32 because i did 32-bytes message strings
> lea dword esi, [errno_table + eax]
> call WriteMsg ; prints a zero-terminated string
To stdout or stderr?
> ret
>
> with the include file looking like this:
> errno_table db 'Operation not permitted ', 10, 0 ; EPERM
> db 'No such file or directory ', 10, 0 ; ENOENT
> [etc...]
> but, this does make my file grow in size, because it's not %define 's or anything,
> as i understand
Makes your file grow in size because you're doing more! I'm against "bloat", but this is "functionallity"!
I've got a "work in progress" (okay, "progress" is optimistic) to do the same thing. I take a slightly different approach, strings of variable length, and a second table of addresses, in which I look up which string to print... Has the advantage that it allows longer strings, if desired, but is more complicated - particulary more complicated to modify into a shared library. I may revert to your method of fixed-length strings... (another option would be to "count zeros" in a block of zero-terminated strings - variable length, to find the one we want. Dog slow, on the face of it, but it isn't *that* big a block of text to walk through, and we're not doing it too often... are we???)
I propose to call this by a macro, like:
...
int 80h
checkerror "we were doing this", exit
which will print the text, so we know where the error happened, print the error message, like you're doing, and jump to the "exit" label (which we assume exists). Won't always be "exit" - we might want to let the user "guess again"... (if eax is < 0FFFFF000h it falls through, of course) For *some* functions, we can get a "negative" value which is valid - memory functions, or perhaps with O_LARGEFILE... for a generic "asm_perror", we ought to do it right, although just "js" is shorter and will work for "most" cases - I still use just "js" ("jns" usually), but it's "slopppy".
If we want to create a smaller "release" version or a "debug" version, we can:
%ifdef DEBUG
; the "good" macro
%else
; the shorter way - "jmp exit"
%endif
%ifdef DEBUG
; our "good" asm_perror
; with all the text
%include "errno.inc", I suppose...
%else
; the shorter way - perhaps nothing
%endif
We can assemble to asm_perror.o, and optionally link against that, as well as the "%include" method. Programmer's choice!
Best,
Frank
-
Couldn't resist trying "call open" instead of int 80h... Getting ": No such file or directory". Closer... But less and less "assembly language"...
Best,
Frank
-
hell, this forum is cutting spaces in the posts...so, you couldn't see that the messages were 30 bytes long ^^
> shl eax, 5 ?
tricky ! but less understandable at first sight :)
there's definitely not enough information about how C functions work. what is possible with C is also possible with asm. i don't know how perror works at all
this is a program that works:
SECTION .text
extern printf
global main
message db "Number to print : %d",10,0
main:
push dword 0x500
push dword message
call printf
add esp,8
--------------------------------
(output)
Number to print : 1280
it tells us that the parameters are pushed in reverse order... but that's all.
with "perror" we're dealing with this famous errno
" errno is defined by the ISO C standard to be a modifiable lvalue of
type int, and must not be explicitly declared; errno may be a macro.
errno is thread-local; setting it in one thread does not affect its
value in any other thread. "
curious enough, perror alone will give "Success", and a second perror (on the next line of later) will give "Invalid seek"
well...i'm giving up too
---------------------------------
%ifdef DEBUG
; the "good" macro
%else
; the shorter way - "jmp exit"
%endif
i like that. pretty convenient actually
i finished this errno-base.inc, équivalent of /usr/include/asm-generic/errno-base.h, and the program i'm working on actually use it when i don't specify a correct file path,
i get "No such file or directory"
yeah!