0xAA55 发表于 2014-5-14 18:40:12

【VS2012】VS2012与NASM联合进行64位编程

很多人都发现好像VS2012不允许x64平台使用_asm语句进行内联汇编。没错,事实就是这样。那么有没有代替的解决方法呢?有。
那就是用NASM编译汇编的文件,然后把它和你的C文件一起链接就行啦。

因为是用NASM做汇编器,所以你必须有NASM汇编器才能编译。
NASM下载地址在此。
顺带请把NASM.EXE放到C:\Windows文件夹。

新建工程

这里要选择空项目,免得预编译头出来烦人。

然后一个工程就弄好了。

先照例新建一个文件:Entry.c

写一些简单的代码。

然后再新建一个文件,用作我们写汇编的文件。取名为123.ASM。其实可以是其它的名字的,这里只是以123.asm为例子。

右键选择该文件,属性,把“项类型”设置为“自定义生成工具”


点右上角配置管理器,新建一个x64的编译目标。


之后设置针对x64目标的编译命令。首先在“平台”那里选“x64”,然后将编译命令设置为
nasm -f win64 "%(FullPath)" -o "$(TargetDir)%(Filename).obj"
再将输出设置为$(TargetDir)%(Filename).obj
“将输出视为内容”选“是”

转到123.asm
写一些简单的代码。

然后再在Entry.c里面添加一些代码。

然后运行。

好啦。这就算配置完了。

那么我们就可以欢快地让NASM的64位汇编与VS2012的64位C语言合体啦~~

接下来是详细的编程方面的教程。

NASM用global语句公开一个符号。我这里示范一下,C语言的int foo=123;是怎么翻译成NASM汇编的。global foo      ;公开符号,注意VS2012的C语言编译器不会在符号前加下划线,但是VC6会,MinGW的GCC、G++也会,切记。

segment .data   ;数据放到数据段。
foo dd123   ;int foo=123;这个时候对于C语言来说,引用它的方法如下:extern int foo;//外部符号然后就可以使用了。而C++是这样引用的:extern"C" int foo;//外部符号请记住区别。

NASM编写函数,举个例子是这样的:global foo      ;公开符号。函数原型:void foo(void);功能:什么也不做。

segment .text   ;代码放在代码段
foo:            ;函数入口
ret             ;什么也不做,直接返回那么C语言怎么引用它呢?很简单。只需提供这个函数的声明就可以使用它了。举例如下:#include<stdio.h>

void foo(void);

int main(void)
{
    foo();
    printf("OK.\n");
    return 0;
}x64编程需要注意的详细的事项:
1、x64默认函数调用约定是__fastcall,第一个参数用rcx寄存器传递,第二个参数用rdx寄存器传递,第三个参数用r8寄存器传递,第四个参数用r9寄存器传递,剩下的参数都用栈传递,而且是逆顺序压栈。
2、调用者维护栈。因此被调用者只需用ret返回即可。请勿使用ret XXXX指令返回,请务必使用ret指令返回。

最后,我会放出已经配置好的工程的下载地址。
SRC下载:

Smileヾ淡莣c 发表于 2014-5-14 21:01:52

看起来好复杂:o

Golden Blonde 发表于 2014-5-14 22:31:54

不顶行不行?:lol

我晕 发表于 2014-5-15 17:27:15

本帖最后由 我晕 于 2014-5-15 17:49 编辑

x64asm的话...
还要注意堆栈需保持16字节对齐
堆栈由调用方分配 调用方收回 最少分配 4*8字节的空间 即无参函数也需要分配空间
在函数中 一般会把寄存器中的前4个参数再放入堆栈中 第1个参数的位置是 因为返回地址已经在堆栈中了 第二个参数在 第五个参数是
前4个参数由rcx rdx r8 r9传递 其余的走堆栈
浮点参数是 xmm0 xmm1 xmm2 xmm3 其余走堆栈
返回值是 rax 或 xmm0
调用win api时的struct成员需要自身长度对齐
额...

fsjaky 发表于 2014-7-7 13:15:39

我以为是64汇编语言!

0xAA55 发表于 2014-7-7 13:35:32

fsjaky 发表于 2014-7-7 05:15
我以为是64汇编语言!

NASM同时支持16位、32位、64位。

0xAA55 发表于 2014-11-19 23:10:27

内容已经更新,那个愚蠢的BUG是升级旧版VS工程导致的。
页: [1]
查看完整版本: 【VS2012】VS2012与NASM联合进行64位编程