我使用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文件调用标签?
答案 0 :(得分:0)
使用指令 extrn 来声明当前源文件之外的函数:
extrn foo:proc
您可以选择使用 public 将本地函数声明为public,但我认为函数默认是公共的。
自VS2015以来,printf现在内联C / C ++代码,至少在64位版本的情况下。解决这个问题的一种方法是使用一个C / C ++源文件来引用printf,在这种情况下,汇编代码可以访问printf。我不知道这是否也适用于sprintf。如果这是一个问题,您将收到链接错误。
答案 1 :(得分:0)
通常需要三种类型的对象来跨文件传输信息。
在用户文件中调用的 source 文件中定义的Proc:默认情况下,在masm中,所有过程都是全局的。因此,源文件不需要声明,用户文件需要声明:
extern <proc_name> : proc
source 文件中定义的变量,由 user 文件中的过程调用:在这种情况下, source 文件需要声明
public <var_name>
并且用户文件必须包含声明:
extern <varname> : var_size ; where var_size is word, qword ymmword...
声明大小必须与extern大小匹配。然而,不确保这种匹配的后果通常是昂贵的。此外,如果变量已声明为extern,并且随后未在该文件中使用,则它仍必须匹配某个文件中的相应公共声明,否则链接器将失败。
相信这有帮助。