Win7 VS2015 NASM汇编语言环境配置


Win7 VS2015 NASM汇编语言环境配置

来源 http://www.cnblogs.com/kileyi/p/7387803.html

参考了以下两个博客文章

http://blog.csdn.net/x356982611/article/details/51260841

http://www.cnblogs.com/antoniozhou/archive/2008/10/23/1318287.html

首先到CodeProject下载NASM的VS配置文件

https://www.codeproject.com/Articles/410776/Integrating-a-compiler-assembler-in-VS-Using-NASM

解压3个配置文件到

C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\BuildCustomizations

也就是和masm的配置文件相同的位置

然后把NASM加入到系统环境变量

D:\nasm-2.13.01

新建一个控制台空工程,同之前MASM的一样,只不过这次选NASM

http://www.cnblogs.com/kileyi/p/7257852.html

建立1个cpp和1个asm文件

cpp01.cpp

1
2
3
4
5
6
7
8
9
10
#include <iostream>
extern"C"voidnasm_function(void);
voidmain()
{
nasm_function();
system("pause");
}

asm01.asm

1
2
3
4
5
6
7
segment .text
global _nasm_function
_nasm_function:
mov eax, 1234h
ret

asm文件上,鼠标右键属性设置

需要注意的一点是,cpp和asm文件要放到NASMTest.vcxproj与.vcproj相同的目录下才能编译,不像MASM可以放在任意目录下,只要把文件添加到

工程就可以编译,NASM的不行,似乎只能放到根目录下才有效,原因不明,说不定可以设置,但是我没找到。

编译应该就能通过了。

有趣的是MASM可以在ASM汇编代码上下断点,而NASM的却不行。不太清楚怎么回事,不过反正可以在cpp函数前下断点,也差不了太多。

在cpp中的nasm_function函数处下断点,单步就能在寄存器中看到eax变成1234了

接下来搞个纯ASM的测试

pure01.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
;filename: sayhellon.asm
;cmd> nasm -fcoff -Xvc sayhellon.asm
;cmd> link sayhellon.obj
extern_MessageBoxA@16 ;in user32.dll
extern_ExitProcess@4 ;in kernel32.dll
global SayHello
global _WinMain
[SECTION .drectve info align=8]
db" /subsystem:windows"
db" /out:sayhellon.exe"
db" /defaultlib:kernel32.lib"
db" /defaultlib:user32.lib"
db" /export:SayHello"
db" /entry:WinMain"
db" /merge:.rdata=.text",0
[SECTION .text USE32 align=16]
szTitle:
db"SayHello",0
szMsg:
db"Hello World!", 0
SayHello:
push 0 ;uType
push dword szTitle ;lpCaption
push dword szMsg ;lpText
push 0 ;hWnd
call _MessageBoxA@16
ret 16
_WinMain:
call SayHello
push 0
call _ExitProcess@4

编译应该就能通过,如果不行,手动设置下工程属性中的入口函数

============================================================

试了下x64不能编译,google了一阵发现是命令行参数的问题。要手动修改一下。

参考了以下例子

http://www.davidgrantham.com/

http://www.davidgrantham.com/nasm-console64/

64位命令行是类似这样调用的

nasm -f win64 ConsoleMessage64.asm -o ConsoleMessage64.obj

打开nasm.xml文件

搜索

Object File

字符串

把原fwin修改为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<EnumValue
Name="0"
DisplayName="Object File 32"
Switch="-f win32"/>
<EnumValue
Name="1"
DisplayName="Object File 64"
Switch="-f win64"/>
<EnumValue
Name="2"
DisplayName="LINUX ELF FORMAT"
Switch="-f elf"/>
<EnumValue
Name="3"
DisplayName="FLAT BINARY"
Switch="-f bin"/>

这样在asm文件上右键属性就可以选64位的参数来编译链接了

新的CPP中调用ASM方法如下

CPP部分不变

1
2
3
4
5
6
7
8
9
10
#include <iostream>
extern"C"voidnasm_function(void);
voidmain()
{
nasm_function();
system("pause");
}

ASM去掉前面的下划线就行了

1
2
3
4
5
6
7
segment .text
global nasm_function
nasm_function:
mov eax, 1234h
ret

纯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
51
52
53
54
55
56
57
58
[SECTION .drectve info align=8]
db" /subsystem:console"
db" /defaultlib:kernel32.lib"
db" /defaultlib:user32.lib"
db" /entry:main"
db" /merge:.rdata=.text",0
NULL EQU 0 ; Constants
STD_OUTPUT_HANDLE EQU -11
externGetStdHandle ; Import external symbols
externWriteFile ; Windows API functions, not decorated
externExitProcess
global main ; Export symbols. The entry point
section .data ; Initialized data segment
Message db"Console Message 64", 0Dh, 0Ah, 0
section .bss ; Uninitialized data segment
alignb 8
StandardHandle resq 1
Written resq 1
section .text ; Code segment
main:
and RSP, 0FFFFFFFFFFFFFFF0h ; Align the stack to a multiple of 16 bytes
sub RSP, 32 ; 32 bytes of shadow space
mov RCX, STD_OUTPUT_HANDLE
call GetStdHandle
mov qword [REL StandardHandle], RAX
add RSP, 32 ; Remove the 32 bytes
lea RSI, [REL Message]
xor RDI, RDI
.LengthLoop: ; Find the string length by searchingfor
cmp byte [RSI + RDI], 0 ; the null terminator
je .LengthDone
add RDI, 1 ; Maximum length, prevents buffer overrun
cmp RDI, 21 ;ifthere is no null terminator
jne .LengthLoop
.LengthDone:
sub RSP, 32 + 8 + 8 ; Shadow space + 5th parameter + align stack
; to a multiple of 16 bytes
mov RCX, qword [REL StandardHandle] ; 1st parameter
lea RDX, [REL Message] ; 2nd parameter
mov R8, RDI ; 3rd parameter
lea R9, [REL Written] ; 4th parameter
mov qword [RSP + 4 * 8], NULL ; 5th parameter
call WriteFile ; Output can be redirect to a fileusing>
add RSP, 48 ; Remove the 48 bytes
xor RCX, RCX
call ExitProcess

优质内容筛选与推荐>>
1、Classic IPC Problems 经典的进程间通信问题
2、web框架
3、2.取出符串“123-456-789-000”中的数字部分,组成一个新的字符串输出
4、JavaScript中HashMap的实现
5、Python切片


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号





    联系我们

    欢迎来到TinyMind。

    关于TinyMind的内容或商务合作、网站建议,举报不良信息等均可联系我们。

    TinyMind客服邮箱:support@tinymind.net.cn