Qt的C ++项目与非内联汇编 [英] Qt C++ Project with non-inline assembly

查看:640
本文介绍了Qt的C ++项目与非内联汇编的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用Windows XP和最新的Qt Creator的与QTSDK和内置的gcc编译器。

现在的问题是,如何利用全装配在C ++的Qt项目。
我知道如何使用内联汇编,但我不知道该怎么办非内联(写在一个单独的文件.ASM)全大会在Qt的C ++项目。

这可能与Qt的C ++项目,如果是这样,怎么样?

编辑:

* 亲文件

 模板=应用
CONFIG + =控制台
CONFIG - = QTSOURCES + = \\
    calc.S

calc.S

 部分。数据
        你好:DB世界,你好!,10
        helloLen:EQU $ -Hello.text段
        全球_start_开始:
        MOV EAX,4
        MOV EBX,1
        MOV ECX,你好
        MOV EDX,helloLen
        INT 80Hproexit:
        MOV EAX,1
        MOV EBX,0
        INT 80H

编译错误

  .. \\ plain_cpp \\ calc.S:汇编的消息:
.. \\ plain_cpp \\ calc.S:1:错误:没有这样的指令:`段.data
.. \\ plain_cpp \\ calc.S:2:错误:没有这样的指令:`分贝72ello世界4410
.. \\ plain_cpp \\ calc.S:3:错误:没有这样的指令:`EQU $ -Hello
.. \\ plain_cpp \\ calc.S:5:错误:没有这样的指令:'.text段
.. \\ plain_cpp \\ calc.S:6:错误:没有这样的指令:`全球_start
.. \\ plain_cpp \\ calc.S:9:错误:`MOV太多的内存引用
.. \\ plain_cpp \\ calc.S:10:错误:`MOV太多的内存引用
.. \\ plain_cpp \\ calc.S:11:错误:`MOV太多的内存引用
.. \\ plain_cpp \\ calc.S:12:错误:`MOV太多的内存引用
.. \\ plain_cpp \\ calc.S:13:错误:EX pression后垃圾'H'
.. \\ plain_cpp \\ calc.S:13:错误:后缀或`INT无效操作数
.. \\ plain_cpp \\ calc.S:16:错误:`MOV太多的内存引用
.. \\ plain_cpp \\ calc.S:17:错误:`MOV太多的内存引用
.. \\ plain_cpp \\ calc.S:18:错误:EX pression后垃圾'H'
.. \\ plain_cpp \\ calc.S:18:错误:后缀或`INT无效操作数

编辑2 - AT& T公司风格

PRO文件

 模板=应用
CONFIG + =控制台
CONFIG - = QTSOURCES + = \\
    calc.S

calc.S

 。数据
你好:
    .string的Hello World \\ n.globl主
主要:
    MOVL $ 4,%EAX
    MOVL $ 1,EBX%
    MOVL $你好,ECX%
    MOVL $ 12%EDX
    INT 0x80的$    RET

错误

 未定义的参考`WinMain函数@ 16'
collect2:劳工处返回1退出状态


解决方案

@karlphillip 的方法一般正确的,你应该记住一些窗口指定的东西:


  1. 当你编译的 @karlphillip 的的code你通过的MinGW 产生链接错误标准库文件:

      C:/ MinGW的/ bin中/../ lib中/ GCC / mingw32的/ 4.6.1 /../../../ libmingw32.a(main.o中):在功能上主要`':
    C:\\ MinGW的\\ MSYS \\ 1.0 \\ SRC \\ mingwrt /../的MinGW / main.c中:73:未定义的引用`WinMain函数@ 16'

    这是不是你的,即 libmingw32.a 的主力。并预计的WinMain 的code的切入点。问题是,的WinMain 是由Microsoft定义Windows应用程序的默认入口点。 libmingw32.a 定义实际为主,是从实际的入口点调用。这主要做一些东西,比电话的WinMain 。但是,你就没有的WinMain 中定义的,很明显。

    在这个简单的例子,你不需要标准库实际,那么你可以删除标准库和编译以上code命令行

      gcc的轮候册,-subsystem,控制台1.S -nostdlib

    应该是等价的Qt设置 QMAKE_CXXFLAGS + = - nostdlib

    然后code以上编译,并... 段错误的。然后进入到第2点:


  2. INT 80H 为特定的Linux系统调用。似乎它不工作在Windows上。你应该调用 WriteConsole 在Windows上写标准输入。但作为一个概念证明,你可以运行下面的code:

     的.text
    .globl主
    主要:
        MOVL $ 1,%eax中
    RET

    这将设置程序退出code为1。


修改
如果你想的世界,你好的例子,用标准库编译包括在内,你可以试试这个:

 。数据
你好:
    .string的Hello World \\ n。文本
。全球_WinMain @ 16
_WinMain @ 16:
    推$你好
    电话_puts
    加$ 4,%ESP    RET

GCC编译1.S

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

解决方案

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

这篇关于Qt的C ++项目与非内联汇编的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆