1.在源文件中添加 test.asm 后缀的asm文件。
2.右键test.asm 文件打开属性
从生成中排出-否
项类型 -自定义生成工具
3.自定义生成工具
设置 “命令行”为 ml64 /Fo $(IntDir)%(fileName).obj /c %(fileName).asm
设置 输出为 $(IntDir)%(fileName).obj,
举例 :ULONG64 myAdd(ULONG64 u1,ULONG64 u2);
asm 文件编译格式如下:
.CODE
myAdd PROC
add rcx,rdx
mov rax,rcx
ret
myAdd ENDP
END
如上面代码我们操作了 rcx,rdx 说明我们的参数有两个.
asm文件内容如下:
.code;代码段
main proc;函数开始
mov rax,120
add rax,34
sub rax,130
ret
main endp;函数结束
在其它需要引用该函数的源文件中,添加以下声明:
```
//声明引用外部函数
EXTERN_C ULONG64 myAdd(ULONG64 u1,ULONG64 u2);
```
ml64/c %(filename).asm
%(filename).obj;%(Outputs)
extrn MessageBoxA: proc
;64位没有 .model 宏指令,不能指定内存模型和调用约定
.data
text db 'Hello World', 0
caption db 'Selph First x64 Application', 0
.code
WinMain proc
sub rsp,28h ; 函数调用前需要预留影子空间,对齐rsp
xor r9d,r9d
lea r8, caption
lea rdx, text
xor rcx,rcx
call MessageBoxA ; 函数调用使用fastcall
add rsp,28h
WinMain ENDP
END ; 最后直接end,不用指明符号
方法2;
创建asm文件,
举例 :ULONG64 myAdd(ULONG64 u1,ULONG64 u2);
asm 文件编译格式如下:
传进来的参数为倒置依次为rcx,rdx,返回rax
.CODE
myAdd PROC
add rcx,rdx
mov rax,rcx
ret
myAdd ENDP
END
右键项目-生成依赖项-生成自定义-勾选masm项
右键asm 文件-属性-项目类-Microsoft Macro Assembler
从生成中排出-否
注意,在asm中如果加载参数为十六进制 字母 开头会报错,需要在字母前面加上 0 ,后面加上 h 如:
.CODE
myAdd PROC
add rcx,rdx
mov rax,0ah //此处如果是数字开头就不需要加0,字母开头需要前面加0
ret
myAdd ENDP
END
在汇编中调用编译函数
1.首先在头文件中声明函数,前面加上 EXTERN_C
EXTERN_C void ShellCodeStart()//举例
{
printf("测试通过");
}
2.然后在asm文件中引入函数如:
注意:因为X64会将参数导入堆栈,导致ret返回地址被覆盖,所以,我们在调用函数前务必先提升栈顶,根据我们传入参数的多少,采取提升多少,完事后,返还原有栈顶
.CODE
extern ShellCodeStart:proc //proc 代表是一个函数的意思
ShellCodeEnd1 PROC
sub rsp,28h //提升栈顶
call ShellCodeStart
add rsp,28h
ret
ShellCodeEnd1 ENDP
END