2017-09-04 54 views
0

装配中的初学者级别。从外部解析未定义的符号

我接收在Visual Studio中的错误是:

1> File2.asm(27):错误A2006:未定义的符号:sprintf的

1> File2.asm(28):错误A2006:未定义的符号:MessageBoxA

文件1是什么处理的计算

文件2就是打印结果的一个窗口。

行处理打印指令是:

invoke sprintf, addr szBuf, offset $interm, eax, edx 
    invoke MessageBoxA, 0, addr szBuf, offset _title, 0 
    invoke ExitProcess, 0 

我在做什么错误的原因是不建?

是因为sprintf是C函数吗?

File1.asm

.386 
.model flat, stdcall 
option casemap :none 

PUBLIC squareroot 
PUBLIC szBuf 
include  \masm32\include\windows.inc 
include  \masm32\include\kernel32.inc 
include  \masm32\include\msvcrt.inc 

includelib \masm32\lib\kernel32.lib 
includelib \masm32\lib\msvcrt.lib 

.data 
    _title db "Result",13,10,0 
    $interm db "%0.4f","+","%0.5f",13,10,0 
    Aval REAL8 1.000 
    Bval REAL8 -2.000 
    Cval REAL8 19.000 
    _fourval REAL8 4.000 
    $Tvalueinc REAL4 1.0,2.00,3.0,4.0,5.0,6.0,7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0 
    $sampleval real10 4478784.0 
    $Powercounter dd ? 
    squareroot dq ? 
    $prevCW dw ? 
    $Tagword dd ? 
    $INT1 dq ? 


    EXTERN Finished:PROC 


.code 
szBuf: 

add eax,4 

fstcw $prevCW 
fwait 
fld Bval ; [loads first instance of b]] 
fmul Bval ; [b*b = b^2] 
fld Aval ;[Load a (a*c)] 
fmul Cval ;(a*c) 
fmul _fourval ;[4*a*c] 
fsubp;[b^2-4*a*c] 
ftst ;compare ST(0) with 0.0 
fstsw ax ;[store camparison results in ax] 
sahf ;transfer flags from AH register 
mov ecx, 0004h 


jb _negative ;jump if <0 
fsqrt ;sqrt(b^2-4*a*c) 



_negative: 
fchs 
fsqrt 
fld $sampleval 
xor eax,eax 
$repeat: 


inc eax 
push eax 
mov ax, $prevCW 
push eax 
fldcw [esp] 
fld $Tvalueinc[ecx] 
fdivp 
fld st(0) 
FRNDINT 
fcomp 
fstsw ax 
Sahf 
fnstenv [ebx-10h] 
movzx eax, word ptr [ebx-10h + 8h] 
fldcw $prevCW 
pop eax 
pop eax 

jz $repeat 
dec eax 
cmp eax, $Powercounter 
add ecx, 0004h 
mov eax, dword ptr squareroot 
mov edx, dword ptr squareroot[0004h] 
jmp Finished 
END szBuf 

File2.asm

.386 
.model flat,stdcall 
option casemap:none 

PUBLIC Finished 
PUBLIC ExitProcess 

include  \masm32\include\windows.inc 
include  \masm32\include\kernel32.inc 
include  \masm32\include\msvcrt.inc 

includelib \masm32\lib\kernel32.lib 
includelib \masm32\lib\msvcrt.lib 

.data 
    _title db "Result",13,10,0 
    $interm db "%0.4f","+","%0.5f",13,10,0 


.code 

Finished: 




    invoke sprintf, addr szBuf, offset $interm, eax, edx 
    invoke MessageBoxA, 0, addr szBuf, offset _title, 0 
    invoke ExitProcess, 0 

END 

回答

0

您正在使用的功能sprintf从MSVCRT.LIB,这是一个C库,它的出口名称为prefixed by an underscore。因此它是_sprintf而不是sprintf

函数MessageBox包含在user32.lib中,因为它没有包含,因此链接程序找不到它。

user32.lib中的函数wsprintfsprintf非常相似,所以如果要节省空间并减小文件大小,可以使用该函数。

sprintfwsprintf都使用C calling convention(与在.model flat,stdcall行中默认设置的STDCALL约定相反)。

注意wsprintf使用C调用约定(_cdecl)而不是标准调用(_stdcall)调用约定很重要。因此,调用进程的职责是将参数从堆栈中弹出,并将参数从右向左推送到堆栈上。在C语言模块中,C编译器执行此任务。

但是INVOKE(更精确地说:its PROTO directive)确实照顾到了,所以现在不用担心。

修正错误的更改/添加这几行代码:

include  \masm32\include\user32.inc 
includelib \masm32\lib\user32.lib 
... 
invoke _sprintf, addr szBuf, offset $interm, eax, edx