具体步骤如下所示:

一 用visual studio新建一个C语言程序空项目

 用visual studio新建一个C语言程序空项目步骤一  用visual studio新建一个C语言程序空项目步骤二

1.添加x64_Inline_assembly.asm

x64_Inline_assembly步骤二 步骤二

2.添加x64_Inline_cpp.cpp

x64_Inline_cpp

二 c语言内连汇编的代码部分

x64_Inline_assembly.asm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
;x64_Inline_assembly.asm
includelib legacy_stdio_definitions.lib

extern printf:proc
;extern MessageBoxA:proc

.data
szHelloWorld db 'HelloWorld',0
szCaption db 'how you doing',0
szFormat db '%s',0
szFormatd db '%d ',0
index dd 0

.code

whatever proc
sub rsp,28h
xor rsi,rsi
xor rbx,rbx
mov rsi,64h
mov rbx,0
jmp loopN
LoopC:
inc rbx
loopN:
mov rdx,rbx
lea rcx,szFormatd
call printf
cmp rsi,rbx
jae LoopC
add rsp,28h
ret
whatever endp
end

x64_Inline_cpp.cpp

1
2
3
4
5
6
7
8
9
10
//x64_Inline_cpp.cpp
#include <stdio.h>

extern "C" void whatever();

int main()
{
whatever();
return 0;
}

补充:需要注意,asm文件和cpp文件同名时编译会产生错误。

三 c语言调用带参数的汇编函数代码部分

补充知识点:rcx寄存器默认第一个参数,rdx为默认第二个,r8默认第三个,r9默认第四个。

x64_Inline_assembly_Parameter.asm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
;x64_Inline_assembly_Parameter.asm
includelib legacy_stdio_definitions.lib

extern printf:proc
extern MessageBoxA:proc

.data
szHelloWorld db 'HelloWorld',0
szCaption db 'how you doing',0
szFormat db '%s',0
szFormatd db '%d ',0
index dd 0

.code
printRK proc
sub rsp,28h
mov rdx,rcx
mov rcx,offset szFormatd
call printf
add rsp,28h
printRK endp

whatever proc
sub rsp,28h
xor rsi,rsi
xor rbx,rbx
mov rsi,64h
mov rbx,0
jmp loopN
LoopC:
inc rbx
loopN:
mov rdx,rbx
lea rcx,szFormatd
call printf
cmp rsi,rbx
jae LoopC
add rsp,28h
ret
whatever endp
end

x64_Inline_cpp_Parameter.cpp

1
2
3
4
5
6
7
8
9
10
11
//x64_Inline_cpp_Parameter.cpp
#include <stdio.h>
#include <windows.h>

extern "C" void printRK(ULONGLONG ulNumber);

int main()
{
printRK(5);
return 0;
}

四 c语言调用带参数并且带返回值的汇编函数的代码部分

补充知识点:寄存器rax作为返回值

x64_Inline_assembly_Parameter_return.asm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
; x64_Inline_assembly_Parameter_return.asm
includelib legacy_stdio_definitions.lib

extern printf:proc
extern MessageBoxA : proc

.data
szHelloWorld db 'HelloWorld', 0
szCaption db 'how you doing', 0
szFormat db '%s', 0
szFormatd db '%d ', 0
index dd 0

.code

MyAdd proc
sub rsp, 28h
add rcx, rdx
mov rax, rcx
add rsp, 28h
ret
MyAdd endp

printRk proc
sub rsp, 28h
mov rdx, rcx
mov rcx, offset szFormatd
call printf
add rsp, 28h
printRk endp

whatever proc
sub rsp, 28h
xor rsi, rsi
xor rbx, rbx
mov rsi, 64h
mov rbx, 0
jmp loopN
LoopC :
inc rbx
loopN :
mov rdx, rbx
lea rcx, szFormatd
call printf
cmp rsi, rbx
jae LoopC
add rsp, 28h
ret
whatever endp
end

x64_Inline_cpp_Parameter_return.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//x64_Inline_cpp_Parameter_return.cpp
#include <stdio.h>
#include <windows.h>


extern "C" ULONGLONG MyAdd(ULONGLONG ulNumber1, ULONGLONG ulNumber2);

int main()
{
ULONGLONG ulRet = MyAdd(1, 3);
printf("%d\n", ulRet);
system("pause");
return 0;
}

补充零碎知识点:

可以新建一个汇编头文件在c语言中包含后可以不使用extern调用汇编函数。

64位寄存器传参rcx,rdx,r8,r9,后面用堆栈[rsp+20h],data,[rsp+28h],data