zoukankan      html  css  js  c++  java
  • 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)MSBuildMicrosoft.Cppv4.0V140BuildCustomizations

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

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

    D: asm-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" void nasm_function(void);
     
    void main()
    {
        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" void nasm_function(void);
     
    void main()
    {
        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
     
    extern GetStdHandle                             ; Import external symbols
    extern WriteFile                                ; Windows API functions, not decorated
    extern ExitProcess
     
    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 searching for
     cmp   byte [RSI + RDI], 0                      ; the null terminator
     je    .LengthDone
     
     add   RDI, 1                                   ; Maximum length, prevents buffer overrun
     cmp   RDI, 21                                  ; if there 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 file using >
     add   RSP, 48                                  ; Remove the 48 bytes
     
     xor   RCX, RCX
     call  ExitProcess
  • 相关阅读:
    如何用 Gerrit 提交代码到服务器
    营收奇迹:三消游戏Candy Crush Saga成功启示录
    flash进阶之路
    Flash笔记之swf居中和swf获取页面参数游戏全屏显示
    如何做一款成功的APP应用
    演义群侠扫盲
    笔记二 air android处理用户交互
    可以准备很多字体,玩家选择性下载
    AIR中调用exe或者bat可执行文件
    很好用的工具类
  • 原文地址:https://www.cnblogs.com/lsgxeva/p/8947873.html
Copyright © 2011-2022 走看看