装配中的初级水平。
我在Visual Studio中收到的错误是:
1> File2.asm(27):错误A2006:未定义的符号:sprintf
1> File2.asm(28):错误A2006:未定义的符号:MessageBoxA
文件1处理计算
文件2是将结果打印到窗口的内容。
句柄打印指令的行是:
Fungeable<Blarg>
我错误的原因是什么?
是因为sprintf是C函数吗?
File1.asm
invoke sprintf, addr szBuf, offset $interm, eax, edx
invoke MessageBoxA, 0, addr szBuf, offset _title, 0
invoke ExitProcess, 0
File2.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
答案 0 :(得分:0)
您正在使用来自MSVCRT.lib的函数sprintf
,它是一个C库,其导出名称为prefixed by an underscore。因此它_sprintf
代替sprintf
。
函数MessageBox
包含在user32.lib
中,你没有包含它,因此链接器找不到它。
user32.lib中的函数wsprintf
与sprintf
非常相似,所以如果你想节省空间并减小文件的大小,你可以使用那个代替。
sprintf
和wsprintf
都使用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