SoLo2 wrote:
> Hello!
>
> I have tried how simple it is to use
> system calls in Linux from assembler.
> Setting parameters in the registers
> eax/edx and then "int 0x80".
>
> I would like to know it there
> is a similar, easy way of calling
> other libraries (specially X windows).
I don't know how "similar" you'd call it, or "easy"... but yes, we
certainly can do that. At some point, there isn't much "advantage" to
using asm...
Might be better to start with a simpler "just call printf" example, but
since you ask about X, I'll append a simple "hello X".
> It should be as simple as giving
> the function name in ASCII ! :)
Well... it won't work in Egyptian hieroglyphics (unless you've got an
Egyptian assembler)... I have seen stuff like:
button db "button", 0
.... mostly in "helper" libraries, not in Xlib itself. I don't know when
or why we have to do that. Mostly it's just "extern XFoo"...
This example links directly with ld. It strikes me that it might be
"dangerous" to be using C library code, without linking in the C startup
code. It "seems to work". I haven't had any trouble with it... (we *do*
need to tell ld which interpreter/dynamic linker to use - ld gets it
wrong by default! gcc knows...) Replace "_start" with "main", if you
want to do it that way...
I have other examples... including accessing Xwindows *without*
libraries - just using the int 80h interface - and even examples that
avoid using ld - creating a "ready to run" executable using Nasm's "-f
bin" mode. How "raw" would you like to get? :)
I'm replying from comp.lang.asm.x86 - I doubt if these other groups are
interested in doing it in assembly language (or are they???). Should
probably trim followups, at some point. There is also interest in this
subject on the news:alt.lang.asm newsgroup...
Best,
Frank
; rudimentary "hello world" for Xwindows
; nasm -f elf -O999 x1.asm
; add the "-g" switch for debugging info - good luck!
;
; sorry 'bout this one...
; ld -o x1 x1.o -I/lib/ld-linux.so.2 -L/usr/X11R6/lib -lX11
;
; if you want it small:
; strip -R .comment x1
;
; after all that, we still have to tell ld where the fun begins:
global _start
; inform Nasm that ld knows where to find this stuff (we hope!)
extern XOpenDisplay
extern XDefaultRootWindow
extern XCreateSimpleWindow
extern XNextEvent
extern XDestroyWindow
extern XCloseDisplay
extern XMapRaised
extern XSelectInput
extern XStoreName
extern XCreateGC
extern XFreeGC
extern XDrawImageString
extern XSetForeground
extern XSetBackground
; we'll be needing lots more of these...
KeyPressMask equ 1 ; mask for XSelectInput
KeyPress equ 2 ; the "type" of event (offset 0 in "glob of bytes")
ExposeMask equ 1 << 15
ExposeEvent equ 12
event_size equ 20h ; ??? max size of several different structs
;------------------------------------------
section .data
StringOpenFailed db "Can't Open X display!", 10
StringOpenFailed_len equ $ - StringOpenFailed
caption db 'A Window', 0
string db ' Greetings from X, Earthling! '
string_len equ $ - string
;-----------------------------------------
;-----------------------------------------
section .bss
Display resd 1
Window resd 1
GC resd 1
event resd event_size
;-------------------------------------
;-------------------------------------
section .text
_start: ; let the ritual begin.
; nop ; parking place for gdb
; open a connection to the server.
; pu****ng 0 uses the "DISPLAY" environment variable
; or defaults to local machine.
push 0
call XOpenDisplay
add esp, 4
or eax, eax
je OpenFailed
mov dword [Display], eax
push dword [Display]
call XDefaultRootWindow
add esp, 4
; error?
push 0 ; background colour
push 0 ; border colour
push 0 ; border width
push 300 ; height
push 400 ; width
push 50 ; top co-ord
push 50 ; left co-ord
push eax ; XDefaultRootWindow, from above
push dword [Display] ; display handle
call XCreateSimpleWindow
add esp, 36 ; C clean-up parameters stuff
or eax, eax
je CreateFailed
mov dword [Window], eax
; this is one Windows doesn't do. if we don't specify
; what events (messages) we want to receive, we don't get any.
push KeyPressMask | ExposeMask
; "or" this with other events to recv!
; don't forget to handle 'em!
push dword [Window]
push dword [Display]
call XSelectInput
add esp, 12
; error?
; give the baby a name
push caption
push dword [Window]
push dword [Display]
call XStoreName
add esp, 12
; error?
; make our window visible.
push dword [Window]
push dword [Display]
call XMapRaised
add esp, 8
; error?
push 0 ; values?
push 0 ; valuemask?
push dword [Window]
push dword [Display]
call XCreateGC
add esp, 16
;error?
mov dword [GC], eax
; Mmmm, looks like 16-bit color, 5-6-5, on my machine.
; Bet we can't count on it!
; push 65535 ; white
push 1111100000000000b ; red
push dword [GC]
push dword [Display]
call XSetForeground
add esp, 12
; error?
; push 0 ; black
push 0000011111100000b ; green
push dword [GC]
push dword [Display]
call XSetBackground
add esp, 12
; error?
Eventloop:
push event
push dword [Display]
call XNextEvent
add esp, 8
; error?
cmp dword [event], ExposeEvent
jnz not_expose
call drawscreen
jmp Eventloop
not_expose:
cmp dword [event], KeyPress
jne Eventloop
; exit gracefully if key pressed
push dword [GC]
push dword [Display]
call XFreeGC
add esp, 8
push dword [Window]
push dword [Display]
call XDestroyWindow
add esp, 8
CreateFailed:
push dword [Display]
call XCloseDisplay
add esp, 4
jmp Terminate
OpenFailed:
mov eax, 4 ; __NR_write
mov ebx, 2 ; stderr
mov ecx, StringOpenFailed ; buffer
mov edx, StringOpenFailed_len ; count
int 80h
Terminate:
mov eax, 1 ; function (sys_exit)
xor ebx, ebx ; exit code
int 80h ; make Linux system call
;-------------------------------------------
;-------------------------------------------
drawscreen:
push string_len
push string
push 140 ; y pos
push 155 ; x pos
push dword [GC]
push dword [Window]
push dword [Display]
call XDrawImageString
add esp, 28
; error?
ret
;---------------------------------------------


|