外部解决不确定的符号



汇编中的初学者级别。

我在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     masm32includewindows.inc
include     masm32includekernel32.inc
include     masm32includemsvcrt.inc
includelib  masm32libkernel32.lib
includelib  masm32libmsvcrt.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     masm32includewindows.inc
include     masm32includekernel32.inc
include     masm32includemsvcrt.inc
includelib  masm32libkernel32.lib
includelib  masm32libmsvcrt.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

您正在使用MSVCRT.lib(即C库)中的函数sprintf,其导出的名称由下sudserscore前缀。因此是_sprintf而不是sprintf

函数MessageBox包含在您不包含的user32.lib中,因此链接器找不到它。

user32.lib中还有 wsprintf的函数,它与 sprintf非常相似,因此,如果要节省空间并降低文件的大小,则可以使用该文件。

sprintfwsprintf都使用C调用约定(与.model flat,stdcall行中的默认值相反)。

注意,重要的是要注意,WSPrintf使用C调用约定(_CDECL),而不是标准调用(_STDCALL)呼叫约定。结果,呼叫过程的责任是将争论从堆栈中弹出,并且参数从右到左将堆叠在堆栈上。在C语言模块中,C编译器执行此任务。

但是INVOKE(更精确:它的PROTO指令)确实要解决此问题,因此请不要担心。

修复错误会更改/将这些行添加到您的代码:

include     masm32includeuser32.inc
includelib  masm32libuser32.lib
...
invoke _sprintf, addr szBuf, offset $interm, eax, edx

最新更新