问题描述
我使用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 的方法一般正确的,你应该记住一些窗口指定的东西:
-
当你编译的 @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点:
-
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:
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 islibmingw32.a
's main. And it expectsWinMain
as entry point of your code. The thing is thatWinMain
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 callsWinMain
. But you have noWinMain
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:
int 80h
is specific linux system call. Seems it doesn't work on windows. You should invokeWriteConsole
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 exit code of program to 1.
EDITIf 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 ++项目与非内联汇编的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!