|
From: Frank Kotler on 19 Apr 2008 04:29 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. ; pushing 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 ;---------------------------------------------
From: SoLo2 on 19 Apr 2008 21:41 On Apr 19, 8:29 am, Frank Kotler <spamt...(a)crayne.org> wrote: > 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. > ; pushing 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 > ;--------------------------------------------- Hello! Thanks to Frank Kotler for his excellent example of assembler i86 and X. [ Also Kleebauer's with the Motorola 68millions version. ] I would like to see that the dynamic libraries are not very dynamic, if the higher abstraction of using an ASCII function name is not used. This is the case as the compilation of the program requires naming and linking some "dynamic" libraries. The program system or programmer could use an "INT 80" with the ASCII library name and then the interrupt delivers the actual method pointer that is faster to use for further calls. Wasn't this already for Linux? Where is this beautifull idea gone? Java? :-) Someone points out that there is doubt a compiler would reach such clean code for an X program as this shown by Mr. Kotler. Greetings, H.Samso ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ http://bits.atari.org http://biis.tripod.com http://so_o2.tripod.com ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
From: Terence on 20 Apr 2008 18:33 An interesting point in Frank Kotler's posting, is who gets to clean up the stack. Here Frank is doing it in the main program (obviously because the called rountines don't do this for him). But I was "brought up" on the Microsoft standard of the CALLED subprogram doing a RET N operation to clear the stack. All my hand- wriiten subroutine include this, beuase my main program is a Microsoft Fortran program which folows my description of the stack responsibility. So I assume Miscroft chnaged it's mind at some point in time, because obvious again, the referred called services aboove are Microsoft- written Windows service.
From: Frank Kotler on 20 Apr 2008 20:33 Terence wrote: > An interesting point in Frank Kotler's posting, is who gets to clean > up the stack. > Here Frank is doing it in the main program (obviously because the > called rountines don't do this for him). > But I was "brought up" on the Microsoft standard of the CALLED > subprogram doing a RET N operation to clear the stack. All my hand- > wriiten subroutine include this, beuase my main program is a Microsoft > Fortran program which folows my description of the stack > responsibility. > > So I assume Miscroft chnaged it's mind at some point in time, because > obvious again, the referred called services aboove are Microsoft- > written Windows service. ??? You'll have to point out the Microsoft written services to me. I missed 'em. Is this what the lawsuit's about??? :) Best, Frank
From: santosh on 20 Apr 2008 22:01 Terence wrote: > An interesting point in Frank Kotler's posting, is who gets to clean > up the stack. > Here Frank is doing it in the main program (obviously because the > called rountines don't do this for him). > But I was "brought up" on the Microsoft standard of the CALLED > subprogram doing a RET N operation to clear the stack. All my hand- > wriiten subroutine include this, beuase my main program is a Microsoft > Fortran program which folows my description of the stack > responsibility. > > So I assume Miscroft chnaged it's mind at some point in time, because > obvious again, the referred called services aboove are Microsoft- > written Windows service. No, the program is for X Windows, whose interface uses the so called "C calling convention", where it's the caller's job to clean-up the stack.
|
Next
|
Last
Pages: 1 2 3 4 Prev: Linking TASM objs with current C++ stuff and linkers Next: Port binding under linux in ASM |