Ite*_*tor 6 windows assembly mingw nasm
我想在Windows上编译Hello World NASM示例.
我已将上面的代码粘贴到一个main.asm文件中,并使用以下命令将其编译为obj文件:
nasm -fwin32 .\main.asm -o main.obj
Run Code Online (Sandbox Code Playgroud)
之后我想将这个obj文件编译成一个exe,如下所示:
g++ .\main.obj -o main.exe -m32
Run Code Online (Sandbox Code Playgroud)
但我得到这个错误:
C:/Program Files (x86)/mingw-w64/i686-8.1.0-posix-dwarf-rt_v6-rev0/mingw32/bin/../lib/gcc/i686-w64-mingw32/8.1.0/../../../../i686-w64-mingw32/lib/../lib/libmingw32.a(lib32_libmingw32_a-crt0_c.o):crt0_c.c:(.text.startup+0x39): undefined reference to `WinMain@16'
Run Code Online (Sandbox Code Playgroud)
我错过了什么?如何修复此错误?
Hello World程序正在尝试手动创建PE导入表.为了使其工作,您需要仔细指示链接器(PE部分不依赖于PE目录,idata只是一个名称).
在该源中进行进一步的假设(例如图像的基地址和CRT的需要).
老实说,这只是胡说八道.正确使用链接器,如Jester所示.
说实话,整个Wikipedia部分充其量只是提供信息.
长话短说:从不使用维基百科作为编程教程.
您可以主要以两种方式创建32位Windows控制台程序:
使用C运行时(CRT)
这使您可以使用常用的C函数(最重要的是printf).
使用CRT有两种方法:
main/ WinMain/ DllMain和Unicode变种)正在由一个正确设置PE的入口点先运行)的CRT调用._mainCRTStartup初始化CRT并且CRT调用您的主要功能. msvcrt.dll适用于Windows安装附带的版本或msvcrtXX0.dllVisual Studio安装附带的版本(XX取决于VS版本).仅使用Windows API
Windows API是操作系统公开的功能,这些是CRT实现最终调用的功能.
您可以使用Windows API和CRT(常见的场景是图形应用程序将CRT静态链接并WinMain用作入口点 - Windows API与C实用程序功能混合使用)或单独使用Windows API.
单独使用它们时,您可以获得更小,更快,更容易制作的可执行文件.
要使用1.1,你需要CRT目标文件,这些文件通常附带一个编译器(它们曾经随Windows SDK一起提供,但现在VS是免费的,微软将它们移到了VS软件包中 - 公平,但VS的数量级比SDK).
1.2和2不需要这些目标文件.
但请注意,编译器/汇编器/链接器兼容性可能是一个令人讨厌的野兽,尤其是.lib用于链接外部API 的机器(基本上libs文件是一种使链接器找到将在运行时由加载器解析的函数的方法 - 即在外部DLL).
首先,写下Hello,World!使用方法2.,请参阅我的另一个答案.
它是在Windows SDK中提供链接器时编写的,今天我使用的是GoLink.
它是一个极简主义,非常易于使用的链接器.
它的一个关键点是它不需要.lib文件,而是可以将它传递给外部函数所在的DLL的路径.
NASM命令是相同的,链接使用:
golink /console /entry main c:\windows\system32\kernel32.dll hello.obj -fo hello.exe
Run Code Online (Sandbox Code Playgroud)
未经测试 - /largeaddressaware如果您的代码可以处理,则可选择添加
这个例子适用于64位编程,它比32位编程更复杂,但无论如何都可能有用.
这就是维基百科文章试图使用的内容.
在分析特定代码之前,让我展示一下我是如何编写它的:
BITS 32
GLOBAL _main
EXTERN printf
EXTERN exit
SECTION .text
_main:
push strHelloWorld
call printf
add esp, 04h
push 0
call exit
SECTION .data
strHelloWorld db "Hello, world!", 13, 10, 0
Run Code Online (Sandbox Code Playgroud)
与Wiki的相比,这非常简单.
要制作可执行文件:
nasm -fwin32 helloworld.asm -o helloworld.obj
golink /console /entry _main c:\windows\system32\msvcrt.dll helloworld.obj -fo helloworld.exe
Run Code Online (Sandbox Code Playgroud)
维基百科的代码创建了一个.idata存储PE导入地址表的部分.
这是一个愚蠢的举动,链接器用于根据目标文件的动态依赖关系生成该表.
要建立该程序链接,我们需要:
0x400000.这可以通过任何链接器完成(用于golink /base 0x400000). .text节开始的位置.我不知道是否link.exe可以.text作为有效的符号名称,或者是否允许指定相对于的入口点,.text但这似乎不太可能.Golink不会允许这样做.简而言之,标签可能缺失. .idata部分.我不知道任何允许这样做的链接器(虽然它可能存在). 简而言之,忘了它.
这就是Jester指出的链接.
汇编代码与1.2相同,但您使用MinGW进行链接.
| 归档时间: |
|
| 查看次数: |
611 次 |
| 最近记录: |