2017-09-04 24 views
0

어셈블리의 초급 단계입니다.정의되지 않은 기호를 외부에서 해결

I Visual Studio에서 수신 오류 :

1> File2.asm (27) : 오류 A2006 : 정의되지 않은 기호 : sprintf를

1> File2.asm (28) : 오류 A2006 : 정의되지 않은 기호 : MessageBoxA

파일 (1) 계산

파일이 인쇄는 창에 결과 무엇을 처리하는 것입니다.

라인 핸들 인쇄 지침은 다음과 같습니다

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

당신은 C 라이브러리 다음 msvcrt.lib에서 기능 sprintf를 사용하고, 그 수출 이름입니다 prefixed by an underscore. 따라서 sprintf 대신 _sprintf입니다.

MessageBox은 포함되지 않은 user32.lib에 포함되어 있으므로 링커에서 찾을 수 없습니다.

user32.lib에도 sprintf과 매우 유사한 기능인 wsprintf이 있습니다. 따라서 공간을 절약하고 파일 크기를 줄이려면 대신 그 파일을 사용할 수 있습니다.

sprintfwsprintf은 모두 줄의 기본값으로 설정된 STDCALL 규칙과 달리 C calling convention을 사용합니다.

참고 wsprintf는 표준 호출 (_stdcall) 호출 규칙 대신 C 호출 규칙 (_cdecl)을 사용한다는 점에 유의해야합니다. 결과적으로 스택에서 인수를 가져 오는 것은 호출 프로세스의 책임이며 인수는 스택에서 오른쪽에서 왼쪽으로 푸시됩니다. C 언어 모듈에서는 C 컴파일러가이 작업을 수행합니다.

그러나 INVOKE (보다 정확하게는 its PROTO directive)이 처리되므로 걱정하지 마십시오.

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

는 코드에 다음 줄을 추가 오류가 변경 수정 /하려면