2017-09-04 53 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