Menu

jwasm...headers...linux...?

Steve A
2012-06-15
2013-04-20
  • Steve A

    Steve A - 2012-06-15

    I've been using jwasm and jwlink on windows for several months now and I am quite pleased with the results.

    I now want to use jwasm and jwlink on linux and would like to know what headers I should use, since there are no linux headers for jwasm that i can see.
    From what I can tell, the h2inc program only works on win32 headers, as it makes no mention of linux.
    What is the procedure for assembling and linking on linux ?

    I don't see this discussed in the docs.
    I assume, that once I have include-able (.inc) headers, that I can use the gcc libraries ?

     
  • Steve A

    Steve A - 2012-06-21

    Okay,…
    I guess the lack of response probably means that not many people know how to use Jwasm on Linux and haven't figured out how to produce usable headers.

    Well, this is screwed.
    Normally, I'd attempt to build my own headers, but, on linux I haven't a clue where to begin.

     
  • Greenhorn

    Greenhorn - 2012-06-23

    It depends on what you want to do.
    AFAIK, the kernel uses the standard C headers.
    If you want to use for graphics and windows the low level API, like in Windoze the WinAPI, search for X11 API.
    If you want to code a Gnome Application, search for the Gnome headers.
    The same is true for QT, but QT is C++.

    Install the dev packages for all that above and search for the headers on your system.

    In the samples for JWASM there are a few examples for Linux, also for X11 and GTK+ and syscalls.

    Try h2incx on the headers on your Windoze system or on WINE. Maybe you must edit the h2incx.ini.

    As you can see, the other threads are also almost unanswered. This is maybe because JWasm is on ice and nobody knows if it will be continued, who knows…

    http://www.the-labs.com/X11/
    http://tronche.com/gui/x/
    http://users.actcom.co.il/~choo/lupg/tutorials/xlib-programming/xlib-programming.html

     
  • Steve A

    Steve A - 2012-06-27

    Thanks greenhorn70,
    Yeh, I searched this forum first and saw that there was not much discussion re: linux.
    I was hoping I'd be able to write code for win-32 and transition it to linux, but, I guess not.
    I'm learning to use gcc and ld as a replacement for jwlink, painful as it is.

    Once I get some stuff figured out, that works in a consistant way, I'll post some tips here.

    Thanks

     
  • Steve A

    Steve A - 2012-07-29

    japheth,
    any help coming in the way of recreating Linux style .inc files from the linux GCC .h headers ?

    I've tried using the win32 tools, but, they simply don't work on the linux headers.
    So far, I've been stripping out the function declarations and manually making proto's.
    Problem is, that doesn't take into consideration any of the other defines and value declarations.

    I'm talking about not just stdio, stdlib, but ncurses, term and as much as possible of the other hundreds/thousands of headers.

    Your suggestions would be greatly appreciated.
    Steve

     
  • japheth

    japheth - 2012-07-31

    Hello,

    > any help coming in the way of recreating Linux style .inc files from the linux GCC .h headers ?

    I understand that it's probably useful, but I also definitely don't want to open another can of worms.

     
  • Steve A

    Steve A - 2012-07-31

    Hey japheth,

    I understand that it's probably useful, but I also definitely don't want to open another can of worms.

    not at all sure why you say that.
    Unless I'm missing something, you can't create any useful linux apps without using headers (.inc files), with jwasm.

    Or are you just saying you don't want to get involved with the recreating linux headers aspect of it ?

    I'm relatively new to jwasm on linux  (I'm only involved at this point due to encouragement by James C Fuller)  and I find linux to be a "can of worms" to begin with.
    With little uniformity and standardization amongst the hundreds of distros, it's a miracle anything works.

    It makes me appreciate programming on Win32.

     
  • japheth

    japheth - 2012-08-01

    > Unless I'm missing something, you can't create any useful linux apps without using headers (.inc files), with jwasm.

    Is this true? IIRC there's the low-level "interrupt 80h" ABI that needs neither prototypes nor headers. Also, NASM, which is kind of "linux oriented", also supplies no headers.

     
  • Steve A

    Steve A - 2012-08-02

    >Is this true? IIRC there's the low-level "interrupt 80h" ABI that needs neither prototypes nor headers.

    I just started reading about low-level linux programming, using interrupts.
    This might be useful.

    >Also, NASM, which is kind of "linux oriented", also supplies no headers.

    Yeh, that puzzles me, because I searched for headers in both Nasm and Fasm and found none.

    What I don't get, is that jwasm requires them, not linux.
    In other words, jwasm complains if I call a library function that has not been previously prototyped.
    So, I at least need the headers for that purpose.
    I have no idea what to do about all the other clutter in the libc headers.

     
  • japheth

    japheth - 2012-08-02

    > What I don't get, is that jwasm requires them, not linux.

    jwasm doesn't "require" prototypes. It's the INVOKE directive that "needs" it.  You can happily use the CRT functions without headers:

    extern c strcpy: near
        push offset src_string
        push offset dst_string
        call strcpy 
        add esp,2*4
    

    All you "need" is an EXTERN or EXTERNDEF directive - and that's exactly what other assemblers also will need.

     
  • Steve A

    Steve A - 2012-08-03

    >jwasm doesn't "require" prototypes.
    >It's the INVOKE directive that "needs" it.  You can happily use the CRT functions without headers:

    Ah!, you see,… that's the problem.
    I've gotten in the habit of using INVOKE converting some MASM code I had written.

    >All you "need" is an EXTERN or EXTERNDEF directive - and that's exactly what other assemblers also will need.

    Funny, I never used to use INVOKE., now I seem to use it all the time.
    Okay, so I should revert back to pushing my params and calling my functions.
    This makes way more sense, than trying to reinvent the LIBC headers.

    I can stop pulling my hair out.
    Thanks japheth

     
  • Steve A

    Steve A - 2012-08-17

    Speaking of "a can of worms"…
    I just can't seem to stop beating a dead horse…

    I've been working on writing a parser for reading-in Linux gcc headers and outputting a Jwasm readable ".inc" file.
    A huge problem is that many gcc headers seem to have little or nothing in common.
    It's plain to see that the gcc headers (like Linux it's self) are nothing more than a patchwork and mish-mash of many, many peoples very different ideas.
    There doesn't seem to be a whole lot of consistancy or continuity in the way the headers are written and the terminology in naming data types.
    When I create a filter to parse one header file, that seems to work, I then have to write a whole new set of filters for the next header file.
    Many "#define"s I simply don't understand and just have to ignore.
    Several function prototypes ("extern"s) are just plain ugly, don't make sense and I also have to ignore them, too.

    I can see why others, in the past, have tried to create a Linux flavored H2INC replacement and have simply given up.
    After the header has been run through the filter, you still have to go back and manually fix many problems.

     
  • mineiro

    mineiro - 2012-09-12

    Hello Sir sarbayo
    do not forget that under linux the path use "/" and under windows path use "\". So, if you edit (search and replace) the header files like "#include <asm/unistd_64.h>" to "#include <asm\unistd_64.h>" you will be able to convert it using h2inc.
    Start by translating unistd_64.h or unistd_32.h . On x86_64, system call to "sys_exit equ 60".
    The same about path is true if you like to translate gtk headers and play with graphical in a more confortable way.
    I have done a macro called scall to deal with system calls on x86_64. It is something like:
    scall rax,rdi,rsi,rdx,r10,r8,r9
    It do something like "scall sys_exit,0":
    mov rdi,0
    mov rax,sys_exit
    syscall
    But, if you like to use library functions on x86_64, so, the invoke macro will be something like:
    invoke function_name,rdi,rsi,rdx,rcx,r8,r9,stack,stack,…
    From my tests, actual version of jwasm do not understand about path on linux, so we cannot  use "include ../test.inc", instead of this, I create simbolic links to that file in actual path, and use "include test.inc". This is a good pratice, so your code can be more portable between different O.S, well, you should setup your environment.
    Hope this help you, because this is the intention. On next post, follow a simple gtk2 sample, and you will be able to compile it under/to win32, linux32, linuxx86_64.

     
  • mineiro

    mineiro - 2012-09-12

    ;target architecture
    _32bits equ 1
    _x86_64 equ 2
    arch equ _x86_64 ;<---[configure me]
    ;target operation system
    linux equ 1
    windows equ 2
    o_s equ linux ;<---[configure me]
    IF arch eq _32bits
    .386 ;.486,...
    .model flat
    base typedef dword
    sbase typedef sdword
    rv00 equ <eax>
    ENDIF
    IF arch eq _x86_64
    base typedef qword
    sbase typedef sqword
    rv00 equ <rax>
    IF o_s eq linux
    OPTION NOKEYWORD:<invoke>
    OPTION NOKEYWORD:<addr>
    include invoke_lnx_64.inc
    ENDIF
    ENDIF
    option casemap:none
    ;---------------------------
    ;include gtk_2_0.inc
    IF o_s eq windows
    includelib gtk-win32-2.0.lib
    ENDIF
    GtkWidget typedef ptr base
    gpointer typedef ptr base
    GdkEvent typedef ptr base
    gtk_init proto c :base,:base
    gtk_window_new proto c :base
    gtk_container_set_border_width proto c :base,:base
    gtk_button_new_with_label proto c :ptr base
    g_signal_connect_data proto c :base,:ptr base,:ptr base,:base,:base,:base
    gtk_container_add proto c :base,:base
    gtk_widget_show proto c :base
    gtk_main proto c
    gtk_main_quit proto c
    gtk_window_set_title proto c :base,:ptr base
    gtk_hbox_new proto c :base,:base
    gtk_box_pack_start proto c :base,:base,:base,:base,:base
    gtk_widget_hide proto c :base
    GTK_WINDOW_TOPLEVEL = 0
    GTK_WINDOW_POPUP = 1
    ;---------------------------
    ;include c.inc
    IF o_s eq windows
    includelib msvcrt.lib
    ENDIF
    exit proto c :base
    ;---------------------------
    ;include glib.inc
    IF o_s eq windows
    includelib glib-2.0.lib
    ENDIF
    g_print proto c :VARARG
    ;---------------------------
    ;include gobject.inc
    IF o_s eq windows
    includelib gobject-2.0.lib
    ENDIF
    ;---------------------------
    IF o_s eq linux
    LF equ 0ah
    ENDIF
    IF o_s eq windows
    LF equ 0dh,0ah
    ENDIF
    entry_point equ <_start> ;entry_point equ <main>
    public entry_point
    EOL equ 0
    TRUE equ 1
    FALSE equ 0
    NULL equ 0
    .data
    szhello db "gtk_init ok, value is %d",LF,EOL
    szno_initialize db "gtk_init not ok, value is %d",LF,EOL
    szshowme db "show it",LF,EOL
    szevtdel db "event deleted",LF,EOL
    szhideme db "hide",EOL
    sztitulo db "testing",EOL
    szclicked db "clicked",EOL
    szdelete_event db "delete-event",EOL
    szdestroy db "destroy",EOL
    szbutton db "click me",EOL
    .data?
    button1 GtkWidget ?
    .code
    delete_event proc C widget:GtkWidget,event:GdkEvent,data:gpointer
    invoke g_print,offset szevtdel
    mov rv00,FALSE
    ret
    delete_event endp
    destroy_event proc C widget:GtkWidget,data:gpointer
    invoke gtk_main_quit
    ret
    destroy_event endp
    IF arch eq _x86_64
    align 16
    ELSE
    align 4
    ENDIF
    button_clicked proc C widget:GtkWidget,data:gpointer
    IF arch eq _x86_64
    IF o_s eq linux
    mov widget,rdi
    mov data,rsi
    ENDIF
    and rsp,-16
    ENDIF
    mov rv00,button1
    .if widget != rv00
    invoke gtk_widget_show,button1
    invoke g_print,data
    .else
    invoke gtk_widget_hide,button1
    .endif
    mov rv00,FALSE
    ret
    button_clicked endp
    main proc C argc:sbase,argv:ptr base
    LOCAL window:GtkWidget
    LOCAL button:GtkWidget
    LOCAL box1:base
    IF arch eq _x86_64
    and rsp,-16 ;;align stack
    ENDIF
    invoke gtk_init,0,0
    .if rv00 == TRUE ;rv00 = return value,eax
    invoke g_print,offset szhello,rv00
    invoke gtk_window_new,GTK_WINDOW_TOPLEVEL
    mov window,rv00
    invoke gtk_window_set_title,window,offset sztitulo
    invoke g_signal_connect_data,window,offset szdelete_event,offset delete_event,NULL,0,0
    invoke g_signal_connect_data,window,offset szdestroy,offset destroy_event,NULL,0,0
    invoke gtk_container_set_border_width,window,20
    invoke gtk_hbox_new,FALSE,0
    mov box1,rv00
    invoke gtk_container_add,window,box1
    invoke gtk_widget_show,box1
    invoke gtk_button_new_with_label,offset szbutton
    mov button,rv00
    invoke g_signal_connect_data,button,offset szclicked,offset button_clicked,offset szshowme,0,0
    invoke gtk_box_pack_start,box1,button,TRUE,TRUE,0
    invoke gtk_widget_show,button
    invoke gtk_button_new_with_label,offset szhideme
    mov button1,rv00
    invoke g_signal_connect_data,button1,offset szclicked,offset button_clicked,NULL,0,0
    invoke gtk_box_pack_start,box1,button1,TRUE,TRUE,0
    invoke gtk_widget_show,window
    invoke gtk_main
    .else
    invoke g_print, offset szno_initialize,rv00
    .endif
    ret
    main endp
    entry_point:
    call main ;create a stack frame
    invoke exit,0
    end entry_point

    "chmod +x lnx_32.sh"

    jwasm -nologo -elf -zcw hello_world.asm
    ld -m elf_i386 -I/lib/ld-linux.so.2 /lib/i386-linux-gnu/libglib-2.0.so.0 /lib/i386-linux-gnu/libc-2.15.so /usr/lib/i386-linux-gnu/libgtk-3.so.0 /usr/lib/i386-linux-gnu/libgobject-2.0.so.0 -o hello_32 hello_world.o
    

    "chmod +x lnx_64.sh"

    jwasm -nologo -elf64 -zcw hello_world.asm
    ld -m elf_x86_64 -o hello_64 hello_world.o -I/lib/x86_64-linux-gnu/ld-2.15.so /usr/lib/x86_64-linux-gnu/libgtk-3.so.0.400.2 /usr/lib/x86_64-linux-gnu/libglib-2.0.so /lib/x86_64-linux-gnu/libc.so.6 /usr/lib/x86_64-linux-gnu/libgobject-2.0.so
    

    note that this macro is so much noob, so it need much work, it's only an example:
    invoke_lnx_64.inc

    invoke      macro   function,s00,s01,s02,s03,s04,s05,s06,s07,s08
        IFNB <s08>
            IF @SizeStr(s08) GE 5
                IFIDN   @SubStr(s08,1,4),<addr>
                    lea rax,@SubStr(s08,5)
                    push rax
                ELSE
                    push s08
                ENDIF
            ELSE
                push s08
            ENDIF
        ENDIF
        IFNB <s07>
            IF @SizeStr(s07) GE 5
                IFIDN   @SubStr(s07,1,4),<addr>
                    lea rax,@SubStr(s07,5)
                    push rax
                ELSE
                    push s07
                ENDIF
            ELSE
                push s07
            ENDIF
        ENDIF
        IFNB <s06>
            IF @SizeStr(s06) GE 5
                IFIDN   @SubStr(s06,1,4),<addr>
                    lea rax,@SubStr(s06,5)
                    push rax
                ELSE
                    push s06
                ENDIF
            ELSE
                push s06
            ENDIF
        ENDIF
        IFNB <s05>
            IF @SizeStr(s05) GE 5
                IFIDN   @SubStr(s05,1,4),<addr>
                    lea r9,@SubStr(s05,5)
                ELSE
                    mov r9,s05
                ENDIF
            ELSE
                mov r9,s05
            ENDIF
        ENDIF
        IFNB <s04>
            IF @SizeStr(s04) GE 5
                IFIDN   @SubStr(s04,1,4),<addr>
                    lea r8,@SubStr(s04,5)
                ELSE
                    mov r8,s04
                ENDIF
            ELSE
                mov r8,s04
            ENDIF
        ENDIF
        IFNB <s03>
            IF @SizeStr(s03) GE 5
                IFIDN   @SubStr(s03,1,4),<addr>
                    lea rcx,@SubStr(s03,5)
                ELSE
                    mov rcx,s03
                ENDIF
            ELSE
                mov rcx,s03
            ENDIF
        ENDIF
        IFNB <s02>
            IF @SizeStr(s02) GE 5
                IFIDN   @SubStr(s02,1,4),<addr>
                    lea rdx,@SubStr(s02,5)
                ELSE
                    mov rdx,s02
                ENDIF
            ELSE
                mov rdx,s02
            ENDIF
        ENDIF
        IFNB <s01>
            IF @SizeStr(s01) GE 5
                IFIDN   @SubStr(s01,1,4),<addr>
                    lea rsi,@SubStr(s01,5)
                ELSE
                    mov rsi,s01
                ENDIF
            ELSE
                mov rsi,s01
            ENDIF
        ENDIF
        IFNB <s00>
            IF @SizeStr(s00) GE 5
                IFIDN   @SubStr(s00,1,4),<addr>
                    lea rdi,@SubStr(s00,5)
                ELSE
                    mov rdi,s00
                ENDIF
            ELSE
                mov rdi,s00
            ENDIF
        ENDIF
        call function
    endm
    

    Hope this help you to have a starting base brother, be in peace.

     
  • mineiro

    mineiro - 2012-09-12

    I come back to say to you take care about that invoke macro if you will use non general registers, and instead of only "push s??", you move that to register rax and push it.

    Below is a simple code to create symbolic links, take care if you will remove links, because it delete the link or file.

    .X64
    option casemap:none
    NULL        EQU 0
    TRUE        EQU 1
    FALSE       EQU 0
    STDIN       EQU 0
    STDOUT      EQU 1
    STDERR      EQU 2
    EOL     EQU 0
    LF      EQU 10
    .data
    erro db "error, received argc==0",LF,00h
    usage db "=---[link]---= create reference to file",LF
          db "usage: ln [-+@] source link_name",LF
          db "option [-=unlink +=symlink @=readlink none=hard_link]",LF     ;;hard link é AND
          db 'eg: ./_ln + _ln.asm reference',LF
          db "eg: ./_ln @ reference",LF
          db "eg: ./_ln - reference",LF
          db "eg: ./_ln + ~/Assembly/Include/unistd64.inc unistd64.inc",LF
          db "eg: ./_ln + /home/Assembly/MessageBox.doc MessageBoxExA",LF,0
    szusage = $ - usage
    sys_link    equ 86
    sys_unlink  equ 87
    sys_symlink equ 88
    sys_readlink    equ 89
    sys_mq_unlink   equ 241
    sys_unlinkat    equ 263
    sys_linkat  equ 265
    sys_symlinkat   equ 266
    sys_readlinkat  equ 267
    sys_exit    equ 60
    .data?
    buffer dq 1024 dup (?)
    argc equ [rsp]
    argv0 equ [rsp+8]
    argv1 equ [rsp+16]
    argv2 equ [rsp+24]
    argv3 equ [rsp+32]
    argv4 equ [rsp+40]
    ;scall rax,rdi,rsi,rdx,r10,r8,r9
    .code
    _start:
      mov eax,argc
      mov rdi,argv1
        .if rdi != 0
            movzx ecx,byte ptr [rdi]
        .endif
        .if eax == 0
            mov edx,sizeof erro
            mov rsi,offset erro
            mov edi,STDERR
            mov eax,sys_write
            syscall
        ;scall sys_write,STDERR,offset erro,sizeof erro
        .elseif eax == 1
            mov edx,szusage
            mov rsi,offset usage
            mov edi,STDOUT
            mov eax,sys_write
            syscall
        ;scall sys_write,STDOUT,offset usage,szusage    ;sizeof usage
        .elseif ecx == "-"          ;unlink argv[2]
            mov rdi,argv2
            mov eax,sys_unlink
            syscall
        ;scall sys_unlink,argv2
        .elseif ecx == "+"          ;create symbolic link betwen argv[2] (source) and argv[3] (destination)
            mov rsi,argv3
            mov rdi,argv2
            mov eax,sys_symlink
            syscall
        ;scall sys_symlink,argv2,argv3
        .elseif ecx == "@"          ;read link of argv[2] and echo it without LF
            mov edx,sizeof buffer
            mov rsi,offset buffer
            mov rdi,argv2
            mov eax,sys_readlink
            syscall
        ;scall sys_readlink,argv2,offset buffer, sizeof buffer
            mov edx,sizeof buffer
            mov rsi,offset buffer
            mov edi,STDOUT
            mov eax,sys_write
            syscall
        ;scall sys_write,STDOUT,offset buffer,sizeof buffer
        .else                   ;create hard link betwen argv[2] and argv[3]
            mov rsi,argv2
            mov rdi,argv1
            mov eax,sys_link
            syscall
        ;scall sys_link,argv1,argv2
        .endif
      mov edi,eax
      mov eax,sys_exit
      syscall
      ;scall sys_exit,rax   ;00h
    END _start
    
     

Log in to post a comment.