Квадрат root [ASM] - PullRequest
       1

Квадрат root [ASM]

0 голосов
/ 14 января 2020

Мне немного трудно понять, как я могу выполнить эту операцию.

    float squared( float num )
    {
       __asm
       {
           push   ebp
           mov    ebp, esp
           sub    esp, num
           xorps  xmm0, xmm0
           movss  dword ptr 4[ebp], xmm0
           movss  xmm0, dword ptr num[ebp]
           mulss  xmm0, dword ptr num[ebp]
           movss  dword ptr 8[ebp], xmm0
           fld    dword ptr 4[ebp]
           sqrtss xmm0, ebp
           movss  ebp, xmm0
           mov    esp,  ebp
           pop    ebp
           ret    0
       }
    }

Я некоторое время работал в C / C ++, и моей задачей всегда было по-настоящему разобраться в том, как работает встроенная сборка, но у меня возникают некоторые проблемы при выполнении код.

Когда я запускаю это в своей основной функции, чтобы напечатать root и вставить значение, я получаю сообщение об ошибке:

Исключение, выданное в 0x00000000 в Test.exe: 0xC0000005: Доступ Нарушение исполняющей локации 0x00000000. произошло

Есть идеи?

Ответы [ 2 ]

3 голосов
/ 14 января 2020

Наиболее фундаментальная проблема с этим кодом заключается в том, что вы написали свой собственный пролог и эпилог функции. Это необходимо делать, когда вы пишете файлы .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 и избавить себя от неприятностей.

0 голосов
/ 18 января 2020

Я думаю, что использование fsqrt с нуля будет работать.

fld qword [num]
fsqrt
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...