Qt C ++ project with non-inline assembly
I am using Windows XP and the latest Qt Creator with QtSDK and built-in gcc compiler.
The question is how to use full assembly in a C ++ Qt project. I know how to use inline build, but I don't know how to do a non-inline (written in a separate .asm file) full build in a Qt C ++ project.
Is this possible with a Qt C ++ project, and if so how?
EDIT:
* pro file
TEMPLATE = app CONFIG += console CONFIG -= qt SOURCES += \ calc.S
calc.S
section .data
hello: db 'Hello world!', 10
helloLen: equ $-hello
section .text
global _start
_start:
mov eax, 4
mov ebx, 1
mov ecx, hello
mov edx, helloLen
int 80h
proexit:
mov eax, 1
mov ebx, 0
int 80h
Compilation errors
..\plain_cpp\calc.S: Assembler messages:
..\plain_cpp\calc.S:1: Error: no such instruction: `section .data'
..\plain_cpp\calc.S:2: Error: no such instruction: `db 72ello world!4410'
..\plain_cpp\calc.S:3: Error: no such instruction: `equ $-hello'
..\plain_cpp\calc.S:5: Error: no such instruction: `section .text'
..\plain_cpp\calc.S:6: Error: no such instruction: `global _start'
..\plain_cpp\calc.S:9: Error: too many memory references for `mov'
..\plain_cpp\calc.S:10: Error: too many memory references for `mov'
..\plain_cpp\calc.S:11: Error: too many memory references for `mov'
..\plain_cpp\calc.S:12: Error: too many memory references for `mov'
..\plain_cpp\calc.S:13: Error: junk `h' after expression
..\plain_cpp\calc.S:13: Error: suffix or operands invalid for `int'
..\plain_cpp\calc.S:16: Error: too many memory references for `mov'
..\plain_cpp\calc.S:17: Error: too many memory references for `mov'
..\plain_cpp\calc.S:18: Error: junk `h' after expression
..\plain_cpp\calc.S:18: Error: suffix or operands invalid for `int'
EDIT 2 - AT&T style
PRO file
TEMPLATE = app CONFIG += console CONFIG -= qt SOURCES += \ calc.S
calc.S
.data
hello:
.string "Hello World\n"
.globl main
main:
movl $4, %eax
movl $1, %ebx
movl $hello,%ecx
movl $12,%edx
int $0x80
ret
ERRORS
undefined reference to `WinMain@16'
collect2: ld returned 1 exit status
source to share
While @ karlphillip's method is correct in general, you should keep in mind some user-defined windows:
-
While you are compiling @ karlphillip's code, you get a linker error generated by the standard library file
MinGw
:c:/mingw/bin/../lib/gcc/mingw32/4.6.1/../../../libmingw32.a(main.o): In function `main': C:\MinGW\msys\1.0\src\mingwrt/../mingw/main.c:73: undefined reference to `WinMain@16'
This is not yours
main
, that is,libmingw32.a
main. And it expectsWinMain
as an entry point for your code. TheWinMain
point is what is the default entry point for a Windows application defined by Microsoft.libmingw32.a
defines the actual main, which is called from the actual entry point. This is the main thing doing some things, not callsWinMain
. Obviously you don'tWinMain
.For this simple example, you don't really need the standard library, then you can drop the standard library and compile the code above with the command line
gcc -Wl,-subsystem,console 1.S -nostdlib
This should be the equivalent Qt job
QMAKE_CXXFLAGS+=-nostdlib
Then the code above is compiled and ... segfaults. Then go to step 2:
-
int 80h
is a linux specific system call. It doesn't seem to work on windows. You must callWriteConsole
on windows to write tostdin
. But as a "proof of concept", you can run the following code:.text .globl main main: movl $1, %eax ret
This will set the exit code of the program to 1.
EDIT If you want a Hello world example compiled with the standard library you can try this:
.data
hello:
.string "Hello World\n"
.text
.global _WinMain@16
_WinMain@16:
push $hello
call _puts
add $4, %esp
ret
Compile with gcc 1.S
source to share
I suggest you read this tutorial to set up Qt Creator correctly for building.
EDIT:
Your problem is that qmake will call gcc to compile your assembly code and you are using Intel Syntax . You need to convert your assembly code to use AT & T syntax :
calc.S
.data
hello:
.string "Hello World\n"
.globl main
main:
movl $4, %eax
movl $1, %ebx
movl $hello,%ecx
movl $12,%edx
int $0x80
ret
calc.pro
TEMPLATE = app CONFIG += console CONFIG -= qt SOURCES += \ calc.S
Paste these 2 files into the same directory then execute qmake
and then make
.
Output:
$ ./calc
Hello World
source to share