我正在编写一个简单的函数来打印堆栈中的浮点值。这个函数是生成的,所以它没有被优化。程序在printf调用时崩溃。
;input: float32 as dword ptr ebp+8
printfloat32:
push ebp
mov ebp, esp
sub esp, 16
;local ptr variable k at dword ptr ebp-4
mov dword ptr ebp-4, lpcstr4 ;which is "%f"
movss xmm0, dword ptr ebp+8
cvtss2sd xmm0, xmm0
sub esp, 8
movsd qword ptr esp, xmm0
push dword ptr ebp-4
call printstr
add esp, 12
mov esp, ebp
pop ebp
ret
printstr
是printf。下面是完整的生成代码:https://pastebin.com/g0Wff0JY
发布于 2019-04-08 08:11:36
看着这张图,我发现可能是一个潜在的问题,但我不知道fasm语法:
call [printstr] ;syntax used for the first call
...
call printstr ;syntax used for the second call that fails
如果printstr是指向函数的基于内存的指针,则第二个调用语法可能试图调用存储该指针的位置,而不是通过使用内存中的值作为指向函数的指针来调用实际的函数。
在Visual Studio的最新版本中,默认的printf和scanf被有效地内联到C/C++代码中,语法相当复杂。
includelib legacy_stdio_definitions.lib ;for scanf, printf, ...
我将问题中的代码转换为masm语法,将printstr更改为printf,并在64位Windows 7专业版上使用Visual Studio 2015测试了32位构建(构建是32位,因此在32位模式下运行)。我对这段代码没有任何问题。我怀疑问题出在不带括号的对printstr的第二次调用中,我将其更正为masm语法转换的一部分。
.data
varf real4 123.75
lpcstr4 db "%f",00ah,0 ;added new line
.code
extern printf:near ;instead of printstr
printfloat32 proc
push ebp
mov ebp,esp
sub esp,16
mov dword ptr [ebp-4], offset lpcstr4
movss xmm0,dword ptr [ebp+8]
cvtss2sd xmm0,xmm0
sub esp,8
movsd qword ptr [esp],xmm0
push dword ptr [ebp-4]
call printf ;was printstr
add esp,12
mov esp,ebp
pop ebp
ret
printfloat32 endp
main proc
push varf ;test printfloat32 function
call printfloat32
add esp,4
xor eax,eax
ret
main endp
end
使用printstr作为指向printf的指针。Masm不需要括号,因为它知道printstr是dd (指向printf的指针)。
.code
extern printf:near
printstr dd printf ;masm doesn't need brackets
printfloat32 proc
; ...
call printstr ;masm doesn't need brackets
; ...
printfloat32 endp
如果printstr位于此源文件的外部,则masm语法将为
extrn printstr:ptr ; or extern printstr:dword
https://stackoverflow.com/questions/55564584
复制相似问题