okay, I'm not entirely sure what to say first, my thoughts seem to be in need of a defragment..

XCB is rated faster than xlib in the tutorial. I think some toolkits have switched to using it for the x protocol instead of xlib. you can read more about it on xcb.freedesktop.org - specifically, the xcb tutorial. Also, it's been ported to win32 - might even make some nice examples for the nasmx project..

fbkotler and I have been trying to get some xcb examples up and running on the yahoo nasm group. Turns out to be a fairly complicated task..

Attached to this post is the latest progress we've (mostly Kotler!) made toward a working example. I think the hardest part of it is understanding the structures behind it. What we tried is to compile an example from the XCB site and try to translate it to NASM syntax.

I think the .inc files are a bit broke - used h2inc and then poked around with them a bit.

The working example is in prog5.asm. my main.asm segfaults on in the program as I never cleaned up the stack. main.asm seems to be a good start especailly at comprehending what's going on, but it needs work.

the main thing throwing us a curve ball in main.asm is the same as prog5.asm - I *think* it has to do with the calling convention of passing a structure. The odd thing is how it takes two paramiters. xcb_setup_roots_iterator takes ebp-24h (frank has a %define for iter_dest) which is somewhere on the stack. It has to do with this one line of C code "s = xcb_setup_roots_iterator( xcb_get_setup(c) ).data;" I get the feeling I'm going to need to pass it the same way in main.asm if I'm to make an progress. I think xcb_generic_iterator_t has to do with it as it's a .data section.

I've been told the way structures on passed on linux in x86 has to do with "i386-ABI" and if they are so many bytes then they are passed through the stack

I might add more to this post in the morning, that's all I can think of right now. Love to hear anyone's thoughts on this - seems to have some potential. It's just parts of it are slightly over my head right now - particularly translating C code to asm in order to just get an understanding of whats going on. I think the "xstruc" macros may even help.
Attachments:
Posted on 2010-05-17 01:36:40 by Brainiac
First off, maybe we should specify that libxcb is an alternative to libXlib. Supposed to be "lighter weight", and faster...

May be worth duplicating, in part, my last message on the subject to the !Yahoo! list. *My* confusion is more from the "secret parameter" than with structures...


Back to XCB... it's really throwing me a curve ball! I've got a
"working" (for me) example, with .inc files and "nice"(?) names and
all... but I don't comprehend what I'm doing! Started off
straightforward enough...

push ebp
mov ebp, esp
sub esp, 120

; of all that, this is all we use?
%define iter_dest ebp-24h

; connect to display
push 0 ; screen
push 0 ; display
call xcb_connect
lea esp,

mov dword , eax

; check for error (lacking the wit to return an error)
push dword
call xcb_connection_has_error
lea esp,

test eax, eax
jz good_conn

; scream and die
push err_msg
call puts
lea esp,
push 1
call exit

good_conn:
push dword
call xcb_get_setup
lea esp,

But now, although you'd never guess it from the C source,
xcb_setup_roots_iterator appears to take two parameters (a "source" and
a "destination"?). The one that shows is the return from get_setup - a
pointer to an xcb_setup_t structure, I believe. The other - a mysterious
location on the stack - appears to be an instance of an
xcb_generic_iterator_t structure... I think...

push eax
; secret parameter?
lea edx,
push edx
call xcb_setup_roots_iterator
; note that the secret parameter is removed by callee!
lea esp,

Looking at the direct disassembly of the C code, I was mystified by...

lea edx,
mov dword , eax
mov dword , edx
call xcb_setup_roots_iterator
sub esp, 4 ; ???

What's the "sub esp, 4" for??? One advantage of doing it "this way" is
that mov is faster than push. The other is that we don't have to clean
up stack after every call. After subtracting a bunch from the stack to
begin with, we're subtracting 4 more after every call... no, after
"certain calls"... Apparently, xcb_setup_roots_iterator ends in "ret 4",
adding 4 to the stack to get rid of that "secret" parameter, and we have
to subtract it again to get back to where we wanted to be...



So we've called xcb_setup_roots_iterator with the address of a memory
area as a "bonus" parameter. This memory gets filled in with an
xcb_???_iterator_t structure - different names for "???" seem to be all
the same structure - "generic" may not be right. The first element,
".data" points to... well, I'd have said an "xcb_setup_t" structure, but
it seems to be a "screen". Other elements are, at offset 4, ".rem"
(count of remaining???), which we don't seem to use, and at offset 8,
".index"... which we use as a "secret parameter" to other calls later. I
may be misinterpreting this.

; "first screen"
mov eax, dword
mov dword , eax

This seems to be a pointer to an xcb_screen_t structure - we use some of
its elements as "normal" parameters to later calls...

I guess it goes along pretty self-explanatory...

...
; set up some data for our window
mov dword , XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK

mov eax, dword
mov eax, dword
mov dword , eax
mov dword , XCB_EVENT_MASK_EXPOSURE\
| XCB_EVENT_MASK_KEY_PRESS

This might be worth pointing out. Unlike Windows, we are notified of
events only if we ask for 'em. In a "real" program, this would be a much
longer list (thus Nasm's line-continuation character '\'). Each of these
constants has one bit set, and we "or" 'em together to tell X which
events we want to see.

Note that when I get to the end, I don't bother cleaning up the stack,
since I'm exiting with "exit()" instead of "ret". Since the "_start:"
label isn't called, we can't "ret". If you wanted to change this back to
an entrypoint of "main:", and end with "ret"... you'd have to fix
that... and preserve ebx, esi, edi...

I do it this way - calling C library functions without linking in C
startup code - just to see if it'll work again. I've been told that, "Of
course you need the startup code if you expect the libraries to work
correctly!" Makes sense to me. But I find that I *don't* need it. So
far, everything I've tried has worked without it. I don't particularly
recommend it, but I keep tryin' it, and it keeps workin'...

The .inc files, xcb.inc and xproto.inc are buggy, no doubt. The parts
I'm actually using seem to be correct. I made a copy of the .h files,
and search-and-replaced the "modern" C syntax that h2incn seems to have
trouble with - uint8_t -> char, etc. There are still a bunch of "size
unknown"s. Some of 'em may be nested structures, as you suggested.
Nasm's built-in "struc" macro doesn't handle nested structures well. We
can do something like:

struc inner
.x resd 1
.y resd 1
.z resd 1
endstruc

struc outer
.a resd 1
.b resd 1
.inner resb inner_size
.c resd 1
endstruc

myinstance istruc outer
endi

and then to access it...

mov eax,

Not pretty. Supposedly, the "xstruc" package available in the
"contributions" section at SourceForge handle nested structures. I've
never gotten around to looking at it. Maybe it's time...

Anyway... I don't know what to make of the "secret parameter". A C++ism?
OOP? (the "this" pointer?) More to the point, I don't know how to tell
if I need it or not! Gcc seems to know... What am I missing? How is an
"invoke"-style macro going to handle this?

Well, we'll be discussing this more, I'm sure. Maybe time to "kick it
upstairs" to the Nasm forum and/or the AsmCommunity forum. There are
some "advanced" guys that hang out at AsmCommunity, especially. You've
noticed that I answer a lot of questions, but I'm better at beginner
questions - which this is turning out not to be! :)


Any of you guys familiar with this "extra parameter" beyond what shows in the C code being passed? In particular, how do we know which functions need it and which don't?

Best,
Frank

Posted on 2010-05-18 18:49:46 by fbkotler
Been quite awhile and no replies, which is fine but I just wanted to add if anyone is having trouble compiling then just say so. it's probably possible to get it to compile if your under windows with the cygwin project since xcb has been ported. I'm on Linux and I think you'll need the libx11-xcb-dev package and *probably* the build-essential package, but I think it's basically just a bunch of sub-packages like gcc , nasm, etc.

I'm not expecting a *solve all our asm problems for us* but that particular parameter is really confusing, and I'm hoping someone could explain it or point us in the right direction.
Posted on 2010-05-22 12:24:26 by Brainiac
Hey, we're up to six downloads! :)

The fact is, there are few people who are interested in accessing Xwindows from assembly language, whether by using Xlib, or this alternative, "XCB", or even (my favorite) no library at all. For practical purposes, you want a much higher level library to deal with Xwindows... and there isn't much advantage to doing it from asm (unless you like to)...

Perhaps the "mystery parameter" question should be re-phrased in terms independent of this particular library. It's the only example I can point to, though... :(

Best,
Frank

Posted on 2010-05-22 22:51:37 by fbkotler