My first forray with JWASM on Linux was successful so I thought I'd post a very simple gtk example.
James
Edit: wrong link.
;=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
;very simple jwasm gtk example
; 1. assemble: ~/jwasm/JWASM -elf -Fo=gtk01.o gtk01.asm
; 2. link with LD: ld -s -o gtk01 gtk01.o -I/lib/ld-linux.so.2 `pkg-config --libs gtk+-2.0`
;=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
.386
.model flat
public _start
gtk_init proto syscall :DWORD, :DWORD
gtk_init_check proto syscall :DWORD, :DWORD
gtk_window_new proto syscall :DWORD
gtk_window_set_title proto syscall :DWORD, :DWORD
gtk_table_new proto syscall :DWORD, :DWORD, :DWORD
gtk_table_attach_defaults proto syscall :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
gtk_container_add proto syscall :DWORD, :DWORD
gtk_button_new_from_stock proto syscall :DWORD
gtk_label_new proto syscall :DWORD
gtk_widget_show_all proto syscall :DWORD
gtk_main proto syscall
gtk_main_quit proto syscall
g_signal_connect_data proto syscall :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
.data
no_int db 'No gtk_init',0
wincap db 'Hello World', 0
labelcap db 'jwasm gtk example', 0
quitbut db 'gtk-quit',0
no_win_err db 'No Window',0
sdel_event db 'delete-event',0
sclicked db 'clicked',0
.data?
window dd ?
table dd ?
gtklabel dd ?
button dd ?
.code
_start: ; let the ritual begin.
;make sure we have gtk
invoke gtk_init_check,0,0
.if (eax == 0)
mov eax, 4 ; __NR_write
mov ebx, 2 ; stderr
mov ecx, offset no_int; buffer
mov edx, sizeof no_int; count
int 80h
jmp Terminate
.endif
;create window
invoke gtk_window_new, 0
.if (eax == 0)
mov eax, 4 ; __NR_write
mov ebx, 2 ; stderr
mov ecx, offset no_win_err; buffer
mov edx, sizeof no_win_err; count
int 80h
jmp Terminate
.endif
mov [window], eax
invoke gtk_window_set_title,[window], offset wincap
invoke gtk_table_new,15, 15, 1
mov [table],eax
invoke gtk_container_add,[window],[table]
invoke gtk_label_new,offset labelcap
mov [gtklabel],eax
invoke gtk_table_attach_defaults,[table],[gtklabel],1, 8, 3, 7
invoke gtk_button_new_from_stock,offset quitbut
mov [button],eax
invoke gtk_table_attach_defaults,[table],[button], 10, 14, 12, 14
;Show whole GUI
invoke gtk_widget_show_all,[window]
;attache signals
invoke g_signal_connect_data,[window],offset sdel_event,offset exit_prog,0, 0, 0
invoke g_signal_connect_data,[button],offset sclicked,offset exit_prog,0, 0, 0
;Do it
invoke gtk_main
;------------------------------------------------------------------------------
;Callback for closing window
exit_prog proc
invoke gtk_main_quit
exit_prog endp
;------------------------------------------------------------------------------
Terminate:
mov eax, 1 ; function (sys_exit)
xor ebx, ebx ; exit code
int 80h ; make Linux system call
end _start
very nice! :U
Thanks for the sample code for JWASM. I grabbed the assembler just about an hour ago and assembled and linked your code in a blink on an Ubuntu 32 9.10 box.
I'm going to go play with gtk now and my new assembler.
This JWASM is nice. Now I can use the MASM code that I have under Linux. :cheekygreen:
For any of the windows lurkers I did this on an old hp7975 2GHz P4 with 512MB, using wubi: http://wubi-installer.org/ (9.04) but it is upgrading to 9.10 as I write.
I am really amazed at the response. One gotcha is it doesn't work with by usb kvm so I have to have a second keyboard to select the linux boot option. After that it finds my keyboard just fine.
James
I never have yet tried wubi. When I was learning Linux and still needed to access Windows from time to time I decided that I did not want to dual boot, so I went to newegg.com and bought some drive drawers/trays so that I could swap the drives. This made it a bunch easier. I ended up buying trays for all my desktop tower cases and after I flushed Windows completely, I have all sorts of drives here that I can use for data storage - and they are a breeze to move from computer to computer if need be.
Going all Linux/BSD is so much fun.
Thanks again for the code. I'm going to use it as a starting point for some ideas that I'd like to flesh out. This JWASM is a pretty nifty assembler.
James,
Nice piece of code. :U
Cool! Is the sample Public Domain? Then I can add it to the JWasm samples dir.
@muttonhead,
You're welcome.
@hutch
Thanks for the compliment. It's been a LONG time since I did any asm coding.
In this instance my fun with BaCon (mentioned in another post somewhere) helped immensely with the gtk code and Linux programming in general.
@japheth
add away. All my posted code is public domain.
There may be problems with Linux noobs as you do have to install development packages. I use Ubuntu 64 9.10 for my main Linux machine ( and BaCon development), but am using Wubi (32) for jwasm, and FreeBasic right now. It's just too big a pia to find all the needed 32bit libraries for use on Ubu64 and I don't have a spare machine at the moment for Ubu32 ( soon to change as I am having too much fun with jwasm).
Thank you japheth for jwasm.
James
This is basically the same as above but uses dynamic loading of the shared libraries.
Did I miss it or is there no debugging jwasm code on Linux?
James
;=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
;very simple jwasm gtk example
;This one uses dynamic loading of shared libraries
; 1. assemble: ~/jwasm/JWASM -elf -Fo=gtk02.o gtk02.asm
; 2. link with LD: ld -s -o gtk02 gtk02.o -I/lib/ld-linux.so.2 -ldl
;=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
.386
.model flat
public _start
;------------------------------------------------------------------------------
;very handy MACRO
_invoke MACRO funcname:REQ,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12,p13,p14,p15,p16,p17,p18,p19,p20
local pos
FOR arg,<p20,p19,p18,p17,p16,p15,p14,p13,p12,p11,p10,p9,p8,p7,p6,p5,p4,p3,p2,p1>
IFNB <arg>
pos=@InStr(1,arg,<ADDR>) OR @InStr(1,arg,<addr>) OR @InStr(1,arg,<Addr>)
IF pos
IF (OPATTR(@SubStr(arg,%pos+5))) EQ 98
lea eax,@SubStr(<arg>,%pos+5)
push eax
ELSE
push OFFSET @SubStr(<arg>,%pos+5)
ENDIF
ELSE
push arg
ENDIF
ENDIF
ENDM
call funcname
ENDM
;------------------------------------------------------------------------------
RTLD_LAZY equ 1
dlopen proto syscall :DWORD, :DWORD
dlclose proto syscall :DWORD
dlsym proto syscall :DWORD, :DWORD
;------------------------------------------------------------------------------
.data
no_init db 'No gtk_init',0
wincap db 'Hello World', 0
labelcap db 'jwasm gtk example', 0
quitbut db 'gtk-quit',0
no_win_err db 'No Window',0
sdel_event db 'delete-event',0
sclicked db 'clicked',0
no_dl db 'No gtk library load',0
no_dl_proc db 'No gtk proc find',0
sz_gtk_lib db 'libgtk-x11-2.0.so',0
sz_gtk_init_check db 'gtk_init_check',0
sz_gtk_window_new db 'gtk_window_new',0
sz_gtk_window_set_title db 'gtk_window_set_title',0
sz_gtk_table_new db 'gtk_table_new',0
sz_gtk_table_attach_defaults db 'gtk_table_attach_defaults',0
sz_gtk_container_add db 'gtk_container_add',0
sz_gtk_button_new_from_stock db 'gtk_button_new_from_stock',0
sz_gtk_label_new db 'gtk_label_new',0
sz_gtk_widget_show_all db 'gtk_widget_show_all',0
sz_gtk_main db 'gtk_main',0
sz_gtk_main_quit db 'gtk_main_quit',0
sz_gobject_lib db 'libgobject-2.0.so',0
sz_g_signal_connect_data db 'g_signal_connect_data',0
.data?
window dd ?
table dd ?
gtklabel dd ?
button dd ?
gtk_lib dd ?
gobject_lib dd ?
gtk_init_check dd ?
gtk_window_new dd ?
gtk_window_set_title dd ?
gtk_table_new dd ?
gtk_table_attach_defaults dd ?
gtk_container_add dd ?
gtk_button_new_from_stock dd ?
gtk_label_new dd ?
gtk_widget_show_all dd ?
gtk_main dd ?
gtk_main_quit dd ?
g_signal_connect_data dd ?
.code
_start:
invoke dlopen,offset sz_gtk_lib,RTLD_LAZY
.if (eax == 0)
mov eax, 4 ; __NR_write
mov ebx, 2 ; stderr
mov ecx, offset no_dl; buffer
mov edx, sizeof no_dl; count
int 80h
jmp Terminate
.endif
mov gtk_lib,eax
invoke dlopen,offset sz_gobject_lib,RTLD_LAZY
.if (eax == 0)
mov eax, 4 ; __NR_write
mov ebx, 2 ; stderr
mov ecx, offset no_dl; buffer
mov edx, sizeof no_dl; count
int 80h
jmp Terminate
.endif
mov gobject_lib,eax
invoke dlsym,gtk_lib,offset sz_gtk_init_check
.if (eax == 0)
mov eax, 4 ; __NR_write
mov ebx, 2 ; stderr
mov ecx, offset no_dl_proc; buffer
mov edx, sizeof no_dl_proc; count
int 80h
jmp Terminate
.endif
mov gtk_init_check,eax
; I'm going to assume the rest are spelled correctly
invoke dlsym,gtk_lib,offset sz_gtk_window_new
mov gtk_window_new,eax
invoke dlsym,gtk_lib,offset sz_gtk_window_set_title
mov gtk_window_set_title,eax
invoke dlsym,gtk_lib,offset sz_gtk_table_new
mov gtk_table_new,eax
invoke dlsym,gtk_lib,offset sz_gtk_table_attach_defaults
mov gtk_table_attach_defaults,eax
invoke dlsym,gtk_lib,offset sz_gtk_container_add
mov gtk_container_add,eax
invoke dlsym,gtk_lib,offset sz_gtk_button_new_from_stock
mov gtk_button_new_from_stock,eax
invoke dlsym,gtk_lib,offset sz_gtk_label_new
mov gtk_label_new,eax
invoke dlsym,gtk_lib,offset sz_gtk_widget_show_all
mov gtk_widget_show_all,eax
invoke dlsym,gtk_lib,offset sz_gtk_main
mov gtk_main,eax
invoke dlsym,gtk_lib,offset sz_gtk_main_quit
mov gtk_main_quit,eax
invoke dlsym,gobject_lib,offset sz_g_signal_connect_data
mov g_signal_connect_data,eax
_invoke gtk_init_check,0,0
.if (eax == 0)
mov eax, 4 ; __NR_write
mov ebx, 2 ; stderr
mov ecx, offset no_init; buffer
mov edx, sizeof no_init; count
int 80h
jmp Terminate
.endif
_invoke gtk_window_new, 0
.if (eax == 0)
mov eax, 4 ; __NR_write
mov ebx, 2 ; stderr
mov ecx, offset no_win_err; buffer
mov edx, sizeof no_win_err; count
int 80h
jmp Terminate
.endif
mov window, eax
_invoke gtk_window_set_title,window, offset wincap
_invoke gtk_table_new,15, 15, 1
mov table,eax
_invoke gtk_container_add,window,table
_invoke gtk_label_new,offset labelcap
mov gtklabel,eax
_invoke gtk_table_attach_defaults,table,gtklabel,1, 8, 3, 7
_invoke gtk_button_new_from_stock,offset quitbut
mov button,eax
_invoke gtk_table_attach_defaults,table,button, 10, 14, 12, 14
;Show whole GUI
_invoke gtk_widget_show_all,window
;attache signals
_invoke g_signal_connect_data,window,offset sdel_event,offset exit_prog,0, 0, 0
_invoke g_signal_connect_data,button,offset sclicked,offset exit_prog,0, 0, 0
;Do it
_invoke gtk_main
;unload the libraries
invoke dlclose,gtk_lib
invoke dlclose,gobject_lib
;------------------------------------------------------------------------------
;Callback for closing window
exit_prog proc
_invoke gtk_main_quit
exit_prog endp
Terminate:
mov eax, 1 ; function (sys_exit)
xor ebx, ebx ; exit code
int 80h ; make Linux system call
end _start
Nice work!,I wish linux had a enforced cross distro backend API, it'd be as fun coding on as windows is, but taking advantage of third party is good too :) is there any benefits to dynamically loading the .so files vs direct callin?
Quote from: E^cube on November 03, 2009, 12:39:45 AM
Nice work!,I wish linux had a enforced cross distro backend API, it'd be as fun coding on as windows is, but taking advantage of third party is good too :) is there any benefits to dynamically loading the .so files vs direct callin?
Most of my Linux experience is with BaCon: http://www.basic-converter.org/ (forum link at the bottom of the page)
It's author explained that with 1,267+ distros at last count, you can never be sure what libraries will be available so he uses dynamic loading. With it you can
provide an alternative say gui vs text. I know on windows a program will just not run without any message as to the problem if a library is missing,
and I assume the same may be true of Linux. It's quite a bit more asm coding but it does give you an alternative.
James
Attached are 3700+ gtk, gdk proto's. Thanks goes out to Peter van Eerten the author of BaCon who made them available for BaCon in a simple format that was easy to parse for use with jwasm. There are some that had variable parameters that my parser converted to a finite number that you might have to adjust.
James
Quote from: jcfuller on November 03, 2009, 11:28:47 PM
Attached are 3700+ gtk, gdk proto's.
Using SYSCALL for GTK isn't the best idea. I realized this when I tried your sample with the Windows version of GTK+. It's better to use the C calling convention and then, for Linux, use JWasm's -zcw switch.
Here's the sample, adjusted for Win32. It "should" also work in Linux, what's changed are the INT 80h's to CRT calls puts() and exit().
;=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
;very simple jwasm gtk example
; create a Linux binary
; 1. assemble: jwasm -elf -zcw -Fo=gtk01.o gtk01.asm
; 2. link with LD: ld -s -o gtk01 gtk01.o -I/lib/ld-linux.so.2 `pkg-config --libs gtk+-2.0`
;
; create a Win32 binary with MinGW
; ( MinGW installed at C:\MinGW, GTK+ installed at C:\GTK )
; 1. assemble: jwasm -elf gtk01.asm
; 2. link with LD: ld -s -o gtk01.exe gtk01.obj -Lc:/gtk/lib
; -lgtk-win32-2.0.dll -lgobject-2.0.dll -Lc:\mingw/lib -lmsvcrt
;=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
.386
.model flat
public _start
gtk_init proto c :DWORD, :DWORD
gtk_init_check proto c :DWORD, :DWORD
gtk_window_new proto c :DWORD
gtk_window_set_title proto c :DWORD, :DWORD
gtk_table_new proto c :DWORD, :DWORD, :DWORD
gtk_table_attach_defaults proto c :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
gtk_container_add proto c :DWORD, :DWORD
gtk_button_new_from_stock proto c :DWORD
gtk_label_new proto c :DWORD
gtk_widget_show_all proto c :DWORD
gtk_main proto c
gtk_main_quit proto c
g_signal_connect_data proto c :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
puts proto c :DWORD
exit proto c :DWORD
.data
no_int db 'No gtk_init',0
wincap db 'Hello World', 0
labelcap db 'jwasm gtk example', 0
quitbut db 'gtk-quit',0
no_win_err db 'No Window',0
sdel_event db 'delete-event',0
sclicked db 'clicked',0
.data?
window dd ?
table dd ?
gtklabel dd ?
button dd ?
.code
_start: ; let the ritual begin.
;make sure we have gtk
invoke gtk_init_check,0,0
.if (eax == 0)
;mov eax, 4 ; __NR_write
;mov ebx, 2 ; stderr
;mov ecx, offset no_int; buffer
;mov edx, sizeof no_int; count
;int 80h
invoke puts, offset no_int
jmp Terminate
.endif
;create window
invoke gtk_window_new, 0
.if (eax == 0)
;mov eax, 4 ; __NR_write
;mov ebx, 2 ; stderr
;mov ecx, offset no_win_err; buffer
;mov edx, sizeof no_win_err; count
;int 80h
invoke puts, offset no_win_err
jmp Terminate
.endif
mov [window], eax
invoke gtk_window_set_title,[window], offset wincap
invoke gtk_table_new,15, 15, 1
mov [table],eax
invoke gtk_container_add,[window],[table]
invoke gtk_label_new,offset labelcap
mov [gtklabel],eax
invoke gtk_table_attach_defaults,[table],[gtklabel],1, 8, 3, 7
invoke gtk_button_new_from_stock,offset quitbut
mov [button],eax
invoke gtk_table_attach_defaults,[table],[button], 10, 14, 12, 14
;Show whole GUI
invoke gtk_widget_show_all,[window]
;attache signals
invoke g_signal_connect_data,[window],offset sdel_event,offset exit_prog,0, 0, 0
invoke g_signal_connect_data,[button],offset sclicked,offset exit_prog,0, 0, 0
;Do it
invoke gtk_main
;------------------------------------------------------------------------------
;Callback for closing window
exit_prog proc
invoke gtk_main_quit
exit_prog endp
;------------------------------------------------------------------------------
Terminate:
;mov eax, 1 ; function (sys_exit)
;xor ebx, ebx ; exit code
;int 80h ; make Linux system call
invoke exit, 0
end _start
Looks good and works on both platforms for me.
Attached are protos with "c"
James
you think you guys can provide a simple example that executes a system cmd and maybe lets you see the results. As to do most things on linux that seems to be the method, so for example shelling "ps" and lettin you get the results back? I believe you can do this using System("ps") in c/c++ idk what thats translates to in assembler.
*update this below example works fine now that I updated ubuntu, that outputs the process list, not gotta figure out how to be able to get that list internally
; 1. assemble: jwasm -elf -zcw -Fo=test1.o test1.asm
; 2. link with LD: ld -s -o test1 test1.o -lc
.386
.model flat
public _start
system proto C :DWORD
.data
ps byte 'ps',0
.code
_start: ; let the ritual begin.
invoke system,addr ps
Terminate:
mov eax, 1 ; function (sys_exit)
xor ebx, ebx ; exit code
int 80h ; make Linux system call
end _start
For the complete linux noobs like me, this is how I got their GTK example to work on a fresh ubuntu(latest version) install
1) install GTK by going to applications->accessories->terminal and paste
sudo aptitude install gnome-core-devel build-essential
2) after that finishes installing, grab JWASM at http://sourceforge.net/projects/jwasm/files/JWasm%20Linux%20binary/JWasm200bl.zip/download
I downloaded to my desktop, right clicked and extracted there
3)go into the JWASM folder, right click on the jwasm file->properties and set its permissions to "allow executable"
5)copy the above example into a file you created called gtk01.asm
this parts optional but I did it for easy compiling(similar to a batch on windows)
4) create a new file and paste the following in it
#!/bin/sh
./JWASM -elf -zcw -Fo=gtk01.o gtk01.asm
ld -s -o gtk01 gtk01.o -I/lib/ld-linux.so.2 `pkg-config --libs gtk+-2.0`
5)right click the file and make it executable like you did the jwasm file, now you can just run this either in a shell via ./whateverunamed it or you can open it and ubuntu will ask if you want to execute or view.
result
(http://img694.imageshack.us/img694/3905/example.png)
I don't plan on doing any low level stuff with jwasm. I dislike "c" and all the {};;; crap so I figured I'd give it a try using the available Linux libraries.
For info (Ubuntu) go into system->Administration->Synaptic Package Manager and install devhelp. Lots of good stuff.
I use Geany as an editor also available from Synaptic Package Manager.
James
can you make static link libraries for linux using jwasm or similar? if so how?