在Visual Studio中链接多个.asm文件

时间:2017-08-02 01:36:10

标签: visual-studio assembly x86 visual-studio-2017 masm

我使用visual studio 2017

让我说一个名为" Factorial.asm"然后我把它分成两个名为" one.asm"的.asm文件。和" two.asm": Factiorial.asm工作正常。

Factorial.asm包含

.386
.model flat, stdcall
option casemap :none  

includelib \masm32\lib\msvcrt.lib
sprintf proto C :vararg
includelib \masm32\lib\user32.lib 
MessageBoxA proto :ptr,:ptr,:ptr,:DWORD
includelib \masm32\lib\kernel32.lib
ExitProcess proto :dword 


.data
   format db "%llu", 13, 10, 0
   _title db "Result",13,10,0

.code

main PROC
    LOCAL szBuf[9]:byte

    mov  eax, 15      ; initial value (low-order bits)
    xor  edx, edx     ; initial value's high-order bits are 0
    mov  ecx, eax     ; loop counter

Factorial:
    dec  ecx          ; decrement counter
    jz   Finished     ; when counter == 0, we're done
    mov  ebx, ecx     ; make copy of counter
    imul ebx, edx     ; high-order bits * multiplier
    mul  ecx          ; low-order bits * multiplier
    add  edx, ebx     ; add high-order product to high-order bits of low-order product
    cmp  ecx, 1
    jg   Factorial    ; keep looping as long as counter > 1

Finished:  
    invoke sprintf, addr szBuf, offset format, eax, edx
    invoke MessageBoxA, 0, addr szBuf, offset _title, 0
    invoke ExitProcess, 0
main ENDP

one.asm包含

.386
.model flat, stdcall
option casemap :none  

includelib \masm32\lib\msvcrt.lib
sprintf proto C :vararg
includelib \masm32\lib\user32.lib 
MessageBoxA proto :ptr,:ptr,:ptr,:DWORD
includelib \masm32\lib\kernel32.lib
ExitProcess proto :dword 


.data
   format db "%llu", 13, 10, 0
   _title db "Result",13,10,0

.code

main PROC
    LOCAL szBuf[9]:byte

    mov  eax, 15      ; initial value (low-order bits)
    xor  edx, edx     ; initial value's high-order bits are 0
    mov  ecx, eax     ; loop counter

Factorial:
    dec  ecx          ; decrement counter
    jz   Finished     ; when counter == 0, we're done
    mov  ebx, ecx     ; make copy of counter
    imul ebx, edx     ; high-order bits * multiplier
    mul  ecx          ; low-order bits * multiplier
    add  edx, ebx     ; add high-order product to high-order bits of low-order product
    cmp  ecx, 1
    jg   Factorial    ; keep looping as long as counter > 1

main ENDP

two.asm包含

Finished:  
invoke sprintf, addr szBuf, offset format, eax, edx
invoke MessageBoxA, 0, addr szBuf, offset _title, 0
invoke ExitProcess, 0

我如何链接" one.asm"和" two.asm"使用Visual Studio 2017.或者换句话说,从单独的.asm文件调用标签?

2 个答案:

答案 0 :(得分:0)

使用指令 extrn 来声明当前源文件之外的函数:

        extrn   foo:proc

您可以选择使用 public 将本地函数声明为public,但我认为函数默认是公共的。

自VS2015以来,printf现在内联C / C ++代码,至少在64位版本的情况下。解决这个问题的一种方法是使用一个C / C ++源文件来引用printf,在这种情况下,汇编代码可以访问printf。我不知道这是否也适用于sprintf。如果这是一个问题,您将收到链接错误。

答案 1 :(得分:0)

通常需要三种类型的对象来跨文件传输信息。

  1. 用户文件中调用的 source 文件中定义的Proc:默认情况下,在masm中,所有过程都是全局的。因此,源文件不需要声明,用户文件需要声明:

    extern <proc_name> : proc

  2. source 文件中定义的变量,由 user 文件中的过程调用:在这种情况下, source 文件需要声明

    public <var_name>
    并且用户文件必须包含声明:

    extern <varname> : var_size ; where var_size is word, qword ymmword...

  3. 声明大小必须与extern大小匹配。然而,不确保这种匹配的后果通常是昂贵的。此外,如果变量已声明为extern,并且随后未在该文件中使用,则它仍必须匹配某个文件中的相应公共声明,否则链接器将失败。

    1. 文件中定义的标签,并从用户文件跳转到:处理与变量相同的处理(案例2)
    2. 相信这有帮助。