内容简介:最近在做一个东西,有少部分的代码需要用汇编写,大部分都是c语言实现,而且还是x64的程序。配置单独的masm开发环境,独立编译然后链接过来,真实太费劲了,所以就想直接用visual studio吧。vs上64位的编译器不支持内敛汇编了,只能写成单独的asm文件,然后独立编译。下面就介绍怎么让让vs2015上让项目支持对asm文件进行编译。在项目上右键->生成依赖项->生成自定义
最近在做一个东西,有少部分的代码需要用汇编写,大部分都是 c语言 实现,而且还是x64的程序。配置单独的masm开发环境,独立编译然后链接过来,真实太费劲了,所以就想直接用visual studio吧。
vs上64位的编译器不支持内敛汇编了,只能写成单独的asm文件,然后独立编译。下面就介绍怎么让让vs2015上让项目支持对asm文件进行编译。
x01 配置项目
在项目上右键->生成依赖项->生成自定义
然后勾选,masm选项:
然后接下来就可以在项目的源文件中添加asm文件。
右键源代码->添加->添加新建项->文件后缀修改为asm。
x02 在汇编中调用C函数和变量
比如我们的 main.c
中定义了一个函数,
void myprint(void) { printf("this is my function\n"); }
想要在汇编中调用,首先需要在项目头文件 stdafx.h
头文件中写如下的声明:
extern "C"//防止函数被name mangling { void myprint(void); __int64 g_iValue = 100; // 定义一个全局变量,注意用extern语法的时候声明和定义的区别。 }
这里用C的方式导出,防止函数名字被粉碎。
接下来,就需要在汇编中写代码来调用c中定义的函数和c中全局变量了。在 proc.asm
写如下代码
EXTERN myprint:PROC ;引用外部函数 EXTERN g_iValue:DQ ;引用外部变量,dq是QWORD,8字节的变量 .DATA val1 DQ ?;自己定义变量 .CODE func2 PROC sub rsp,28h ; 这个地方可能是为了栈空间对齐,不这样做有可能会崩掉,原因未知。反正反汇编一x64的代码都有这个东西 call myprint mov r10,g_iValue ; 此处使用中的stdafx.h全局变量。 mov val1,r10 ; 使用自定义的变量 mov rax,val1 ; 写入返回值 add rsp,28h ret FUNC2 ENDP END
这样就可以实现在汇编中调用C的函数了。
0x3 在C语言中调用汇编的函数
上面代码写完之后,编译可以通过,但是我们并看不到执行的结果,因为汇编中的 func2
还并没有被我们调用,想要调用汇编中的 func2
,首先需要在头文件 stdafx.h
中做如下声明:
extern "C" __int64 __stdcall func2();
然后在main函数中调用:
int main() { __int64 ret = func2(); printf("%ld",ret); return 0; }
就可以看到输出:
this is my function 100
0x4 在汇编中调用win64 api
有时候需要在汇编中调用windows的64位的API,在调用API之前首先要明白函数调用约定。
在32位系统中我们调用的用户态API一般都遵循 WINAPI(__stdcall)
的调用约定,主要规则有两条: 1. 函数参数由右向左入栈;2. 函数调用结束后由被调用函数清除栈内数据(其实是被调者参数的清除)。所以在调用一个遵循 WINAPI
的函数之后,不需要自己来做被调函数栈空间的清除,因为被调函数已经恢复过了。而在x64汇编中,两方面都发生了变化。一是前四个参数分析通过四个寄存器传递:RCX、RDX、R8、R9,如果还有更多的参数,才通过椎栈传递。二是调用者负责椎栈空间的分配与回收。
下面写一个调用 MeesageBoxA
的实例代码:
INCLUDELIB kernel32.lib ; 告诉连接器链接这个动态库 EXTERN MessageBoxA:PROC ; 引用 MessageBoxA函数 .DATA ; 定义局部变量 szCaption db '恭喜',0 szText db '当您看到这个信息的时候,您已经可以编译Win32汇编程序了!',0 .CODE func2 PROC sub rsp,28h mov rcx, 0 mov rdx, offset szText; mov r8, offset szCaption mov r9, 0 call MessageBoxA add rsp,28h ret FUNC2 ENDP END
看雪上的大佬说 sub rsp,28h
是为了给被调用函数的参数和返回地址预留栈空间,这个说法应该是对的,不留会报错的。
至于语法高亮,可以使用 AsmDude
这个插件,还有代码提示功能,用起来很舒服。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- iOS汇编入门教程(一)ARM64汇编基础
- iOS 汇编入门教程(一):ARM64 汇编基础
- iOS汇编入门教程(三)汇编中的 Section 与数据存取
- iOS汇编入门教程(二)在Xcode工程中嵌入汇编代码
- 汇编语言8086笔记
- python编程(反汇编)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Java Language Specification, Java SE 7 Edition
James Gosling、Bill Joy、Guy L. Steele Jr.、Gilad Bracha、Alex Buckley / Addison-Wesley Professional / 2013-2-24 / USD 59.99
Written by the inventors of the technology, The Java(r) Language Specification, Java SE 7 Edition, is the definitive technical reference for the Java programming language. The book provides complete, ......一起来看看 《The Java Language Specification, Java SE 7 Edition》 这本书的介绍吧!