none
Ассемблерный код в C++ RRS feed

  • Вопрос

  • Доброго времени суток, пытаюсь инициализировать поля структуры используя ассемблерную вставку в функции, компилятор выдает ошибку (Ошибка 3 error C2415: недопустимый тип операнда) код выглядит так:

    void CALLBACK TestAsm()
    {
       TPipeDataStruct SendData;
       __asm
       {
          MOV     SendData.FTerminate, false
          MOV     SendData.FStage, STAGE_1
       }
    }
    Скажите пожалуйста что я делаю неправильно.

    2 августа 2017 г. 5:05

Ответы

  • Видимо потому что константа C++ находится в памяти, а команд память/память в x86 нет.

    Попробуйте так:

    mov eax, STAGE_1

    mov SendData.FStage, eax

    Скорее всего про false ассемблер и вовсе ничего не знает.

    Забавно так же что код скорее всего хуже чем получится при нормальном присвоении в C++.


    This posting is provided "AS IS" with no warranties, and confers no rights.

    2 августа 2017 г. 16:16
    Модератор
  • Я проверял только с неименованным enum:

    typedef enum  
    {
    	STAGE_1 = 1
    } ;

    Для enum'ов с именем не знаю, как это работает.

    3 августа 2017 г. 5:48

Все ответы

  • а что такое STAGE_1?
    2 августа 2017 г. 7:48
  • STAGE_1 Это константа имеет вид 
    const int STAGE_1 = 1;
    2 августа 2017 г. 10:10
  • Видимо потому что константа C++ находится в памяти, а команд память/память в x86 нет.

    Попробуйте так:

    mov eax, STAGE_1

    mov SendData.FStage, eax

    Скорее всего про false ассемблер и вовсе ничего не знает.

    Забавно так же что код скорее всего хуже чем получится при нормальном присвоении в C++.


    This posting is provided "AS IS" with no warranties, and confers no rights.

    2 августа 2017 г. 16:16
    Модератор
  • Ну да, const в С++ на сколько я знаю - не "константа" а, скорее, "переменная только для чтения". Конечно, оптимизирующий компилятор не выделяет память под const-переменную, если ее значение известно на этапе компиляции и мы не берем на нее указатели. Но в ассемблерный код она уходит как переменная, поэтому применить mov таким образом не получится. Вместо const-переменной нужно использовать enum, элемент перечисления всегда воспринимаются как "истинная" константа.

    Что касается false (написанного маленькими буквами), то да, он не работает в ассемблере. Но можно использовать FALSE, или просто 0.

    3 августа 2017 г. 3:04
  • Суть в том что не надо никакого ассемблера, есть все шансы что будет медленнее. Если на старинных процессорах человек вполне мог оптимизировать код, на современных моделях это практически нереально. Куда больше шансов что "оптимизация" вызовет либо простой либо сброс конвейера и будет только хуже.

    Если есть время и желание то займитесь оптимизацией алгоритма, а не кода.


    This posting is provided "AS IS" with no warranties, and confers no rights.

    3 августа 2017 г. 3:40
    Модератор
  • Большое спасибо за советы, про FALSE помогло а вот с enum почему то не получилось возможно я просто что то неправильно сделал код теперь выглядит так:

    typedef enum  tagStageEnum : int
    {
    	STAGE_1 = 1
    } StageEnum;
    
    
    void CALLBACK TestAsm()
    {
       TPipeDataStruct SendData;
       __asm
       {
          MOV     SendData.FTerminate, FALSE //Тут теперь все норм
          MOV     SendData.FStage, StageEnum::STAGE_1
       }
    



    3 августа 2017 г. 5:17
  • Цель этого кода просто попытка научиться использовать ассемблерный код и C++, я не ставлю цель что то оптимизировать,  к сожалению я только начал изучать С++ и ассемблер, их изучение и есть сама цель. Я очень благодарен за оказанную мне помощь и за ваши ответы, спасибо.  
    3 августа 2017 г. 5:21
  • Я проверял только с неименованным enum:

    typedef enum  
    {
    	STAGE_1 = 1
    } ;

    Для enum'ов с именем не знаю, как это работает.

    3 августа 2017 г. 5:48
  • Спасибо все получилось.
    3 августа 2017 г. 6:51