Глядя на изображение, я вижу, что может быть потенциальной проблемой, но я не знаю синтаксис 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:
includelib legacy_stdio_definitions.lib ;for scanf, printf, ...
Я преобразовал код из вопроса в синтаксис masm, изменил printstr на printf и протестировал 32-битную сборку с использованием VisualStudio 2015 на 64-битной Windows 7 Pro (сборка 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