На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
  
> Как загрузить в регистр CPU значения указателя , VC++ 2019 inline assembler
    Привет всем. Не знаю, куда правильно помещать тему - сюда или в раздел по ассемблеру.

    Пишу функцию обработки изображения на си. Хочу написать на inline ассемблере (точнее надо, это принципиально, неважно).
    Заготовка для функции:
    ExpandedWrap disabled
      void RasterDithering(uint8_t* pPixels, uint32_t dwWidth, uint32_t dwHeight)
      {
          uint32_t dwOneVal = 1;
          uint32_t dwRevWidth;
          uint8_t *pPixelData;
       
          __asm
          {
              mov ebx, [pPixels]                              ; ebx: = указатель на пиксели
              test ebx, ebx                                   ; Выход, если
              jz L10                                          ; указатель == 0
       
              mov [dwOneVal], 1
              mov ecx, [dwHeight]                             ; ecx: = высота картинки
              mov eax, [dwRowBytes]                           ; eax: = длина строки
              dec ecx                                         ; ecx: = высота - 1
              mul ecx                                         ; edx:eax: = eax * ecx
              add ebx, eax                                    ; ebx == pPixelData - указатель на последнюю
              mov [pPixelData], ebx                           ; строку изображения
       
      ........................
      //        lea ecx, [pPixelData]                           ; ecx = pPixelData; // указатель на последнюю строку изображения
      //        mov ecx, [pPixelData]                           ; ecx = pPixelData; // указатель на последнюю строку изображения
              mov ecx, pPixelData                             ; ecx = pPixelData; // указатель на последнюю строку изображения


    Все команды до mov [pPixelData], ebx включительно работают нормально и правильно. Надо загнать значение указателя pPixelData в ecx. Да, в данном месте можно сделать mov ecx, ebx и забыть, но после mov [pPixelData], ebx есть масса других команд. Поэтому грузить надо из [pPixelData].

    Проблема такая:
    Любая из 3 последних команд под отладкой дают ошибку - см скрин.
    Как сделать правильно?

    Почему mov ebx, [pPixels] вверху работает, а внизу такой же mov ecx, [pPixelData] валится?

    спасибо.
    Прикреплённая картинка
    Прикреплённая картинка
      Цитата hd44780 @
      Любая из 3 последних команд под отладкой дают ошибку - см скрин.
      Ну у меня в 19-й вижуалке вторая ваша команда всё нормально делает:
      ExpandedWrap disabled
        void tt( unsigned char *ppt)
        {
            unsigned char *ggh;
            __asm {
                mov ebx, [ppt]
                inc ebx
                mov [ggh], ebx
                inc ecx
                mov ecx, [ggh]
            }
        }
        Вот тут на что-то похожее жалуются https://github.com/opencv/opencv/issues/15690

        Правда, без ассемблера, на чистом сишнике, но ошибка ровно как у меня. Попробую я VC++ грохнуть и переставить, может какие-то апдейты кривые пришли.
        Сообщение отредактировано: hd44780 -
          Ситуация совершенно непонятная. Ни одна из трёх команд не может бросать этого исключения. По ссылке почти наверняка пример неподдерживаемой процессором инструкции, сгенерированной компилятором, например, SIMD из нереализованного в нём набора SSEx, но тут стандартный i386. Чтобы ассемблер неверно сгенерировал код, а дизассемблер полностью зеркально скрыл этот факт? Не верю.
          Могу предположить три варианта:
          • баг отладчика или системного ПО, например, антивируса; не исключено, что точка останова int 3 неверно обрабатывается в среде;
          • проявление зловреда, не отловленного антивирусом; именно подобным образом по времена DOS палились многие вирусы под TD386;
          • разогнанный процессор.
          Разгон кристалла ещё и не такие выкрутасы умеет. hd44780, попробуй вынести эту функцию в отдельный .asm и скомпилить специализированным Ассемблером. Например, NASM или хотя бы MS-ым MASM. Так же не помешает посмотреть байты кода, желательно не в отладчике, а в листинге по ключу -Fa. Ну и попытаться проверить все три предположения путём смены инструмента явно лишними мне будут.
            Рекомендую прогнать через дизассемблер свой exe и увидеть, что там фактически сгенерировалось на этом месте:
            ExpandedWrap disabled
              dumpbin /disasm my_exe.exe /out:my_exe.asm



            И я конечно не знаю как msvc разруливает все эти конфликты использования регистров, флагов и пр. Знаю, что во времена Borland C любое использование было на свой страх и риск, ничего не синхронизировалось вообще. В gcc во встроенном ассемблере нужно обязательно указывать все, что ты потенциально мог испортитьиспользовать.
            Сообщение отредактировано: shm -
              Спасибо всем. Как и ожидалось после прочтения https://github.com/opencv/opencv/issues/15690 снос и переустановка VC 2019 решила все эти проблемы.

              Вот и ставь после этого все эти апдейты :D .

              Тему пока замораживаю, т.к. эта работа ещё идёт.
                По поводу отладки асм-кода в VS я скажу, что это полное дно.
                Я нечасто юзаю студию для отладки кода на асме, но точки останова там постоянно ставятся мимо и курсор ходит мимо (открываешь отладчик Ctrl+Alt+D и видишь, что код исходника там один, а дизасм другой).
                Сбивают всё пустые строки (и закомментированные соответственно), насколько я помню (полгода уже, наверное, не отлаживал там асм-код).

                Плюс ко всему, регистры ebx, esi, edi, ebp нужно сохранять и восстанавливать при изменении (или не использовать их). На этот счёт есть соглашение о вызовах.
                Исключение может возникнуть по этой причине, но не в самом асм-коде, а уже после него (либо если вызывать какие-то функции из асм-кода).

                Не знаю, дело ли в обновлении или в том, что отладчик тупо показывает не ту строку, а по факту из-за изменения ebx возникает исключение в коде за асм-блоком.
                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                0 пользователей:


                Рейтинг@Mail.ru
                [ Script execution time: 0,0367 ]   [ 21 queries used ]   [ Generated: 28.03.24, 11:41 GMT ]