企鹅's Blog

Happy coding

Hello GTK+ in Linux Assembly Language

企鹅 posted @ 2009年5月09日 00:13 in 未分类 with tags gtk+ , 11246 阅读

学着书里的例子,写一个 GTK+ 程序:

 

# Hello GTK+ in Assembly
#
# as -g asm-gtk.s -o asm-gtk.s.o
# gcc asm-gtk.s.o `pkg-config --libs gtk+-2.0` -g -o test
# ./test
#
# Author: Pengu1n , Date: 20090508
#

 .section .data

 # Strings
 APP_TITLE:
 .ascii "GTK+ in ASM\0"

 HELLO_ASM:
 .ascii "Hello ........ ASM!\0"

 BUTTON_CLICKED_INFO:
 .ascii "Hello button clicked!\n\0"
 .equ BUTTON_CLICKED_INFO_LEN, . - BUTTON_CLICKED_INFO    # '.' means current address

 # Constants
 .equ GTK_WINDOW_TOPLEVEL, 0
 .equ NULL, 0

 # GTK+ Signal name
 signal_button_clicked:
 .ascii "clicked\0"

 signal_delete_event:
 .ascii "delete_event\0"

 .section .bss

 .equ WORD_SIZE, 4
 .lcomm main_window, WORD_SIZE
 .lcomm hello_button, WORD_SIZE

 .section .text

 .global main
 .type main, @function

main:

 pushl %ebp
 movl  %esp, %ebp   # args is here, but howto get &argc ?

 # TODO: pass &argc, &argv to gtk_init
 pushl $NULL
 pushl $NULL
 call  gtk_init
 addl  $8, %esp

 pushl $GTK_WINDOW_TOPLEVEL
 call  gtk_window_new
 addl  $4, %esp
 movl  %eax, main_window

 pushl $APP_TITLE
 pushl main_window
 call  gtk_window_set_title
 addl  $8, %esp

 # Setup destory singal handler
 pushl $NULL
 pushl $NULL
 pushl $NULL
 pushl $destroy_handler
 pushl $signal_delete_event
 pushl main_window
 call g_signal_connect_data    # g_signal_connect is just a macro,
                               # so we must call g_signal_connect_data directly
 addl $24, %esp

 pushl $HELLO_ASM
 call  gtk_button_new_with_label
 addl  $4, %esp
 movl  %eax, hello_button

 # Setup destory singal handler
 pushl $NULL
 pushl $NULL
 pushl $NULL
 pushl $button_clicked_cb
 pushl $signal_button_clicked
 pushl hello_button
 call g_signal_connect_data
 addl $24, %esp

 pushl hello_button
 pushl main_window
 call gtk_container_add
 addl  $8, %esp

 pushl main_window
 call gtk_widget_show_all
 addl  $4, %esp

 call gtk_main

 movl $1, %eax
 movl $0, %ebx
 int  $0x80

 .type destroy_handler, @function
destroy_handler:

 pushl %ebp
 movl  %esp, %ebp

 call gtk_main_quit

 movl $0, %eax
 leave
 ret

 .type button_clicked_cb, @function
button_clicked_cb:

 pushl %ebp
 movl %esp, %ebp

 movl $4, %eax          # syscall __NR_write
 movl $1, %ebx          # stdout
 movl $BUTTON_CLICKED_INFO, %ecx
 movl $BUTTON_CLICKED_INFO_LEN, %edx
 int $0x80

 movl $0, %eax
 leave
 ret

 

 

 

遗留问题:还没有找到如何传 argc, argv 给 gtk_init。

 

Avatar_small
cjacker 说:
2009年9月23日 20:20

程序启动后,堆栈指针esp指向的就是参数个数,后面是第一个参数的指针,依次向下。参数指针后有一个0x00000000空位,然后是环境变量。

所以,取个数,就是(%esp),取参数依次加4,要取环境变量,则跳过

(1+参数个数+1)*4的偏移即可。

 

.section .data

output:

.asciz "There are %d params\n"

output2:

.asciz "%s\n"

.section .text

.globl _start 

_start:

        nop

movl (%esp), %ecx

pushl %ecx

pushl $output

call printf

addl $4, %esp

popl %ecx

   movl %esp, %ebp

     addl $4, %ebp

para_loop:

pushl %ecx

pushl (%ebp)

pushl $output2

call printf

addl $8, %esp

popl %ecx

addl $4, %ebp

loop para_loop

 

pushl $0

call exit

Avatar_small
porterleete 说:
2011年12月15日 00:43

谢谢你这段代码。它已在过去的一个很大的帮助,我也有理由期待它有助于在未来。我使用谷歌翻译,所以我道歉,我的话引起任何误解。

在翻译的情况下是不合适的,这里是我的母语我的话:

Thank you for this code. It has been a great help in the past, and I have reason to expect it being helpful in the future. I am using Google translate, so I apologize for any misunderstanding caused by my words.

In case the translation is unsuitable, here are my words in my native language:


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter