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
  • 相关阅读:
    HDU2027 统计元音 一点点哈希思想
    湖南工业大学第一届ACM竞赛 数字游戏 字符串处理
    湖南工业大学第一届ACM竞赛 我素故我在 DFS
    HDU3293sort
    HDU2082 找单词 母函数
    HDU1018 Big Number 斯特林公式
    湖南工业大学第一届ACM竞赛 分糖果 位操作
    UVA 357 Let Me Count The Ways
    UVA 147 Dollars
    UVA 348 Optimal Array Multiplication Sequence
  • 原文地址:https://www.cnblogs.com/lsgxeva/p/8947873.html
Copyright © 2011-2022 走看看