汇编中的初学者级别。
我在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
非常相似,因此,如果要节省空间并降低文件的大小,则可以使用该文件。
sprintf
和wsprintf
都使用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