3

I am using Windows XP, and Newest Qt Creator with QtSDK and the built-in gcc compiler.

The question is, how to use full assembly in a C++ Qt Project. I know how to use inline assembly, but I don't know how to do non-inline(written in a separate .asm file) full assembly, 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

Compile 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
L123
  • 139
  • 4
  • 14

3 Answers3

2

While @karlphillip method correct in general, you should take in mind some windows specified stuff:

  1. While you compile @karlphillip's code you get linker error produced by MinGw standard library file:

    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'
    

    That is not your main, that is libmingw32.a's main. And it expects WinMain as entry point of your code. The thing is that WinMain is default entry point for windows application defined by Microsoft. libmingw32.a defines actual main, that is called from actual entry point. That main does some stuff and than calls WinMain. But you have no WinMain defined, obviously.

    In this simple example you needn't standard library actually, then you can drop standard library and compile above code with command line

    gcc -Wl,-subsystem,console 1.S -nostdlib
    

    It should be equivalent Qt setting QMAKE_CXXFLAGS+=-nostdlib

    Then code above compiles, and... segfaults. Then go to point 2:

  2. int 80h is specific linux system call. Seems it doesn't work on windows. You should invoke WriteConsole on windows to write to stdin. But as a "proof of concept" you can run the following code:

    .text
    .globl  main
    main:
        movl $1, %eax
    ret
    

    This will set exit code of program to 1.

EDIT If you want Hello world example, compiled with standard library included, 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

Lol4t0
  • 12,444
  • 4
  • 29
  • 65
  • Is it possible to use the standard library calls (`puts` for example) WITHOUT using WinMain? I'd like to define `start` or `main` as an entry point. I'm trying to inform the linker to use `main` as an entry point (`-emain`), but it doesn't work: it still demands `WinMain@16`. And when I add `-nostdlib`, then it doesn't recognize `puts` on the other hand ;-/ Where's `puts` located? What lib should I link with? – SasQ Jul 07 '12 at 17:40
  • @SasQ, Even if you redefine entry point, you still link to standard library and it requires `int main()` defined in your code. If you redefine entry point, this main will never be called. You can just create empty `main()`. But I think you are looking for troubles while trying to use standard library with custom entry point: Custom entry point means initialization code will not be ran, global objects will not be created, probably standard library functions will refuse to work – Lol4t0 Jul 07 '12 at 20:12
  • I found what I was doing wrong: The linker didn't see my `puts` because I used `_puts` (name mangling), but it appears that on x86_64 target GCC uses no mangling by default (along with other ABI breakages, like using registers for passing parameters etc.). My code was written for x86 (32-bit) which uses different call conventions (name mangling, pushing parameters on the stack etc.). From the same reasons it didn't see my `main` function, which I had called `_main`. After those changes it worked. Huh... One needs to learn all life long... :-P – SasQ Aug 02 '12 at 00:56
1

I suggest you read this tutorial to properly setup Qt Creator for assembly.

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 in the same directory then execute qmake , followed by make.

Output:

$ ./calc 
Hello World
karlphillip
  • 92,053
  • 36
  • 243
  • 426
  • Thanks. I c that kills all the QT and C++ build steps. Thus only allowing for projects which are pure assembly. I take it mixing full assembly src files, and C++/Qt src files in a Qt project is not possible? – L123 Mar 16 '12 at 18:13
  • Updated answer. The issue is that you are using Intel syntax. Check my example. – karlphillip Mar 16 '12 at 18:17
  • Thanks, so I need to use AT&T style with GCC? I tried what you suggested, code in original post, got error. – L123 Mar 16 '12 at 18:39
  • I added the full example. It works on my Linux with gcc/g++. If you have any problems, you will have to paste the error here. I suggest you create a new folder to perform the test above. – karlphillip Mar 16 '12 at 18:45
  • Doesn't work. I see you're on Linux. Interesting. Using Win XP here. `WinMain@16' error. – L123 Mar 16 '12 at 18:52
  • Interesting is that you tell us that it doesn't work, but you don't share what exactly is the error (or error msg) you are observing. Can't help you any further, good luck. – karlphillip Mar 16 '12 at 18:54
  • The fact is that if GCC is able to compile *calc.S* on the cmd-line with `gcc calc.S -o calc` it should work with qmake/make. – karlphillip Mar 16 '12 at 18:55
  • Karl, I do tell you the error messg. Look at the top of this page. :) Look in section EDIT 2. I posted the code I tried based on your suggestion before you posted the same code, I also copy pasted the exact error messages. – L123 Mar 16 '12 at 18:59
  • undefined reference to `WinMain@16' – L123 Mar 16 '12 at 19:03
  • Thanks, it wasn't clear to me that you were having **the same error** as before. I don't have a Windows box setup for this test, but I suggest you start to [read about this error here](http://stackoverflow.com/q/5259714/176769). – karlphillip Mar 16 '12 at 19:22
  • Just to clarify a few things, if you try to build a simple .pro file that compiles a minimal C++ application (hello world), this problem you are reporting happens or not? – karlphillip Mar 16 '12 at 19:40
  • Everything works ok as long as I don't try to add any assembly. – L123 Mar 16 '12 at 19:59
0

Have you tried SOURCES += yourfile.asm in your *.pro file?

  • It is not clear, which compiler would be used for assembly here? gcc/g++? That is what comes with Qt and that is what I have selected. This only supports inline assembly right (which does not support many things like labels and .data section)? – L123 Mar 16 '12 at 18:15
  • @L123 Wrong. `gcc` does support translating assembly files (`*.s`) to object code. And it does support inline assembly, which may even contain pseudo ops like ".data" and jumps to local labels defined in the inline assembly. It is only you who doesn't know about this, read the gcc online docs and the chapter about inline assembly. – Gunther Piez Mar 17 '12 at 10:12