Menu

A simple GTK+ 2.0 Program in NASM

2004-02-03
2013-06-04
  • Nobody/Anonymous

    ;=================================================
    ; gtk-test.asm by Yeoh HS
    ; 26 January 2004
    ; A very simple GTK+ program. :-)
    ; My first GTK program built using NASM
    ;
    ; Credits To:  numit_or for his gnometest example
    ;
    ;================================================
    ;# Makefile --------------------------------------
    ;GTK_LIBS = `pkg-config --libs gtk+-2.0`
    ;
    ;gtk-test: gtk-test.o   
    ;    gcc $(GTK_LIBS) -Wall -s -o gtk-test gtk-test.o
    ;
    ;gtk-test.o: gtk-test.asm
    ;    nasm -f elf  -l gtk-test.lst gtk-test.asm
    ;
    ;clean:
    ;    rm *.o gtk-test
    ;# ----------------------------------- End Makefile

    GLOBAL main
    GTK_WINDOW_TOPLEVEL equ 0

    EXTERN gtk_init
    EXTERN gtk_window_new
    EXTERN gtk_main
    EXTERN gtk_widget_show
    EXTERN exit

    ;------------------------- Data Section ---
    SECTION .data USE32

    ;------------------------- Code Section ---
    SECTION .text USE32

    main:
        push ebp        
        mov ebp, esp
        sub esp, 8

        lea eax,[ebp+8]
        lea ebx,[ebp+12]

        push ebx
        push eax
        call gtk_init
        add esp, 8        

        push GTK_WINDOW_TOPLEVEL
        call gtk_window_new
        add esp, 4
        mov [appPtr],eax

        push dword [appPtr]
        call gtk_widget_show   
        add esp, 4

        call gtk_main

        push dword 0
        call exit

    ; end of main

    ;--------------- Uninitialized Data Section ---
    SECTION .bss
    appPtr: resd 1

    ; end of file

     
    • Nobody/Anonymous

      To see more Linux nasm examples, go to this group:
      http://groups.yahoo.com/group/linux-nasm-users

      Best Regards,
      Yeoh
      --
      New code:
      gtk-hello.asm uploaded to linux-nasm-users group.

       
    • Nobody/Anonymous

      Uploaded gtk-hello2.zip to the group:

      http://groups.yahoo.com/group/linux-nasm-users

      This version connects a button to a callback function. When button is clicked the program quits.

      Best Regards,
      Yeoh
      --

       
    • Nobody/Anonymous

      I think you can use one 'USE32' at the beginning of the file, but not 'USE32' after every SECTION.

       
    • Frank Kotler

      Frank Kotler - 2004-12-08

      "-f elf" defaults to 32-bits anyway, so it really isn't neccessary at all...

      Best,
      Frank

       
    • Nobody/Anonymous

      It would be good for beginners if you commented on each line of code.

       
    • Nobody/Anonymous

      good job

       
    • Nobody/Anonymous

      Please could you comment your code?

       
    • Nobody/Anonymous

      my makefile, copied from your source:

      1 # Makefile --------------------------------------
      2 GTK_LIBS = `pkg-config --libs gtk+-2.0` 

      4 gtk-test: gtk-test.o 
      5  gcc $(GTK_LIBS) -Wall -s -o gtk-test gtk-test.o

      7 gtk-test.o: gtk-test.asm
      8  nasm -f elf -l gtk-test.lst gtk-test.asm 

      10 clean:
      11  rm *.o gtk-test
      12 # ----------------------------------- End Makefile

      execution:
      # make
      Makefile:5: *** missing separator.  Stop.

      AC

       
    • Nobody/Anonymous

      i don't understand the beginning
      push ebp 
      mov ebp, esp
      sub esp, 8
      lea eax,[ebp+8]
      lea ebx,[ebp+12]

      i think the stack is as follows

      ^ 0
      | argv (=pointer to "gtk-test")
      | argc (=1)

      there is only one push, then ebp is assigned the adress of esp, that is, 4 bytes below argc
      [ebp+8] should be argv and [ebp+12] should be 0 !?

       
    • Nobody/Anonymous

      Sheee... lemme see...

      We have here a "C style main". So the "_start" label is in the "startup" code. At that point, we have:

      ??? actual strings of args and env?
      dword 0 ; end of envp
      ??? ; pointers to 0-terminated strings for
          ; environment variables.
      dword 0 ; end of argv
      ??? ; pointers to 0-terminated strings for
          ; command line parameters - at least 1!
      pointer to name of this program
      dword argc

      Now, "behind our back", C calculates envp and argv, and pushes them...

      envp
      argv
      argc

      Then, C calls main:

      return address for main's caller

      That's where we get control. Now, in "our" code, we push ebp.

      old ebp

      So... "ebp + 8" is argc and "ebp + 12" is argv. Looks right to me. Did you miss the return address of main's caller?

      Best,
      Frank

       
    • Nobody/Anonymous

      yeah, i missed that
      i didn't understand because there is no "return adress" in my other asm prog :
      _main:
      pop eax     ; argc !

      so, this gtk-test is linked with gcc, and that implies "C-style functions" ?
      any other things like this to know when using gcc ?

       
      • Nobody/Anonymous

        I don't know much about gcc - I try to avoid it. Strictly speaking, it's ld that does the linking, gcc just passes the command line to ld. In this case, since there's nothing to compile, that's all it does. By default, it links in some "startup" code - crt0.o or so - which does some preliminary housekeeping and calls main. You can override this with "--nostartfiles" (maybe only one "-").

        I don't know what command line(s) you used to build your other asm program, but if argc was the first thing on the stack, it wasn't called. The "call" instruction puts a return address on the stack. The only thing C really has to do with it is that it "hides" a call instruction...

        Another thing gcc knows to pass on the command line to ld, if you're using shared libraries (which is what GTK+ is... and libc), is the correct name for the dynamic linker. By default, ld looks for /lib/ld-linux.so.1. This doesn't exist, on my system. If I've got a file like:

        extern puts
        global _start

        _start:
        push msg
        call puts
        ...

        Assemble it with "nasm -f elf myfile.asm", as usual, and link with "ld -o myprog myprog.o -lc", attempting to run it results in "no such file or directory", even though the file is plainly there. Most confusing!!! Gotta tell ld "-I/lib/ld-linux.so.2" (or "--dynamic-linker ... - "-I" - interpreter - is shorter :)

        Lessee - C expects functions to preserve ebx, esi, and edi (as well as the more obvious ebp and esp). If you're writing something to be called from C, you have to take care of this. If you're calling a C function... the other registers may be altered by the function - save 'em if you need 'em!

        Lessee - printf expects "floats" to be double precision...

        sub esp, 8
        fst qword [esp]
        push format_string
        call printf

        I guess that's all I know right now...

        Best,
        Frank

         
    • Nobody/Anonymous

      my asm prog wasn't called, it's a simple asm code linked with ld:
      nasm -f els prog.asm
      ld -s -o prog prog.o

      now, i'm trying to print the arg with the "C-like" code, and i can't

      with prog.asm, very simple:
      _start:
          mov esi, [esp+4]
          call WriteString

       
    • Nobody/Anonymous

      with this "C-like" asm code:
      main:
          push    ebp
          mov    ebp, esp
          mov esi, [ebp+12]
          call WriteString       ; doesn't work :-(

      note, i tried using both lea and mov (can't find out the difference)

       
      • Nobody/Anonymous

        Hi,
        don't using Linux I've no glue your [esp+12] really is the argv vector, but generally this argv will be a pointer to a pointer - as defined with **argv. So, you have to de-reference your pointer twice! For doing that, take the mov version of your code
        mov eax, [esp+12] ;bits32 asumed
        mov eax, [eax]    ;2nd de-reference
        call ...
        That should work!
        martin

         
    • Nobody/Anonymous

      gives a segfault :(

       
    • Nobody/Anonymous

      ahh, no ! it works ^^ thank you

       
    • Nobody/Anonymous

      hey that's really cool, it's a pointer to an array of pointers. so i get the argument i pass to my prog this way:
          mov eax, [ebp+12]
          mov eax, [eax+4]
          call WriteStr
      thanks

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.