Наиболее фундаментальная проблема с этим кодом заключается в том, что вы написали свой собственный пролог и эпилог функции. Это необходимо делать, когда вы пишете файлы .ASM полностью вручную, но вы должны , а не делать это, когда вы пишете «встроенную» сборку, встроенную в C. Вы должны позволить компилятору обрабатывать стек. Это наиболее вероятная причина сбоя программы. Это также означает, что все ваши попытки получить доступ к аргументу num
вместо этого получат доступ к некоторому несвязанному слоту стека, поэтому, даже если ваш код не обработал sh, он потребовал бы ввод мусора,
Как Как указано в комментариях к вопросу, у вас также есть куча бессмысленных инструкций, например, sqrtss xmm0, ebp
(sqrtss
не может принимать аргументы целочисленного регистра). Это должно было привести к тому, что компилятор отклонил программу, но если вместо этого он генерировал бессмысленный машинный код, это также могло бы вызвать взлом sh.
И (также, как указано в комментариях к вопросу), я ' Я не уверен, какую математическую функцию этот код будет вычислять в гипотетическом сценарии, когда каждая машинная инструкция выполняет то, что вы хотели, но определенно не квадрат root.
Правильная встроенная сборка в стиле MSV C для реализации квадрата с плавающей точкой одинарной точности root с использованием инструкции SSEn sqrtss
выглядела бы примерно так, я думаю. (Не проверено. Так как это Win32, а не Win64, реализация, использующая fsqrt
, может быть более подходящей, но я не знаю, как это сделать, не задумываясь.)
float square_root(float radicand)
{
__asm {
sqrtss xmm0, radicand
}
}
... Или вы можете просто #include <math.h>
и использовать sqrtf
и избавить себя от неприятностей.