Thursday, April 07, 2005

Qt programing in assembly

Spent lunch hacking up a Qt hello world application in assembly. Yes, I did do this because I found it (and things like this) fun. It isn't very portable and will probalby break if you try to link it to qt built by a gcc other then gcc3. Also I left the hard coded memory offsets in there. Feel free to "optimize" it. :) Of course this wouldn't be complete without a screenshot:



Copy the code into a file: "hello_world.s" and then run
gcc hello_world.s -lqt-mt
./a.out

File: hello_world.s
/**
* Qt Hello World in assembly
*/
.data
.HELLO_STRING:
.string "Hello World!"
.CONNECT1:
.string "1quit()"
.CONNECT2:
.string "2clicked()"

.text
.align 2

.globl main
main:
/* Store the stack */
pushl %ebp
movl %esp, %ebp

/* Create QApplication */
/* Arguments: argc, argv */
subl $260, %esp
andl $-16, %esp
movl $0, %eax
subl %eax, %esp
movl 12(%ebp), %eax
movl %eax, 8(%esp)
leal 8(%ebp), %eax
movl %eax, 4(%esp)
/* Grab some memory */
leal -88(%ebp), %eax
movl %eax, (%esp)
call _ZN12QApplicationC1ERiPPc


/* Make a QPushButton */
/* Arguments: 0, 0 */
movl $0, 8(%esp)
movl $0, 4(%esp)
/* Grab some memory */
leal -232(%ebp), %eax
movl %eax, (%esp)
call _ZN11QPushButtonC1EP7QWidgetPKc

/* Make QString and set the button text to it*/
/* Argument: "Hellow World!" */
movl $.HELLO_STRING, 4(%esp)
/* Grab some memory */
leal -248(%ebp), %eax
movl %eax, (%esp)
/* Call the QString constructor */
call _ZN7QStringC1EPKc

/* Set the QString as the argument */
leal -248(%ebp), %eax
movl %eax, 4(%esp)

/* Grab some memeory */
leal -232(%ebp), %eax
movl %eax, (%esp)
call _ZN7QButton7setTextERK7QString

/* free QString memeory */
leal -248(%ebp), %eax
movl %eax, (%esp)
call _ZN7QStringD1Ev

/* Connect button press to quiting */
/* Arguments: QObject, button and clicked signal */
movl $.CONNECT1, 12(%esp)
leal -88(%ebp), %eax
movl %eax, 8(%esp)
/* arg 2 QObject, qapp and quit slot */
movl $.CONNECT2, 4(%esp)
leal -232(%ebp), %eax
movl %eax, (%esp)
call _ZN7QObject7connectEPKS_PKcS1_S3_


/* set the main widget to be the button */
leal -232(%ebp), %eax
movl %eax, 4(%esp)
leal -88(%ebp), %eax
movl %eax, (%esp)
/* Set the button as the main window */
call _ZN12QApplication13setMainWidgetEP7QWidget


/* Show the button */
/* Call the show event on qapp */
leal -232(%ebp), %eax
movl %eax, (%esp)
call _ZN7QWidget4showEv


/* qapp exec */
/* Argument: the button */
leal -88(%ebp), %eax
movl %eax, (%esp)
call _ZN12QApplication4execEv


/* cleanup button and qapplication memeory */
movl %eax, -240(%ebp)

leal -232(%ebp), %eax
movl %eax, (%esp)
call _ZN7QButtonD1Ev

leal -88(%ebp), %eax
movl %eax, (%esp)
call _ZN12QApplicationD1Ev

movl -240(%ebp), %eax

/* exit the app */
leave
ret

Here it is in c++
#include "qapplication.h"
#include "qpushbutton.h"

int main( int argc, char **argv )
{
QApplication a(argc,argv);

QPushButton button(0);
button.setText( "Hello World!" );

QObject::connect( &button, SIGNAL(clicked()), &a, SLOT(quit()) );
a.setMainWidget( &button );
button.show();

return a.exec();
}

No comments:

Popular Posts