2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему На страницу 1, 2  След.
 
 С++, Win7, __asm вставки (процессор Pentium)
Сообщение17.03.2013, 23:53 


05/09/12
2587
Пишу в вижуал Студии, делаю ассемблерные вставки, хочу вызывать си-процедуру, в которой тоже ассемблер - просто поменять значение одного регистра, не хочу никаких стеков, ОЗУ и прочего. При выходе похоже не восстанавливается из стека адрес возврата и программа вылетает. Подскажите, где ошибка? (Лишние куски кода убрал для краткости)
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
unsigned char expand_CL(void)
{
        //unsigned char y;
        __asm{
                //MOV CL, x
                AND CL, BIN8(00000111)
                CMP CL, 3
                JB M1
                INC CL
M1:             CMP CL, 7
                JB M2
                INC CL
M2:             RET //MOV y, CL
        }
        //return 0;
}
unsigned int _8_to_10(unsigned char x)
{
        unsigned int y;
        __asm {
        MOV EAX, 0
        MOV AL, x
        CMP AL, BIN8(11110000)
        JB N1
                //y = (x&BIN8(00001100))<<6 | BIN8(10101010);
                AND AL, BIN8(00001100)
                SHL EAX, 6
                OR  EAX, BIN8(10101010)
                JMP M_end
N1:     CMP AL, BIN8(11000000)
        JB N2
                AND AL, BIN8(00110000)
                SHL EAX, 4

                MOV CL, x
                CALL expand_CL

//              AND CL, BIN8(00000111)
//              CMP CL, 3
//              JB M1
//              INC CL
//M1:           CMP CL, 7
//              JB M2
//              INC CL
//M2:           //RET

                MOV CH, x
                TEST CH, BIN8(00001000)
                JZ M3
                OR  EAX, BIN8(00001010)
                SHL CL, 4
                OR  AL, CL
                JMP M4
M3:             OR  EAX, BIN8(10100000)
                OR  AL, CL
M4:             JMP M_end

N2:     //else {

M_end:
        MOV y, EAX
        }
        return y;
}
 

 Профиль  
                  
 
 Re: С++, Win7, __asm вставки (процессор Pentium)
Сообщение18.03.2013, 00:14 
Заслуженный участник
Аватара пользователя


06/10/08
6422
А Вы можете сгенерированный компилятором ассемблерный код показать?

 Профиль  
                  
 
 Re: С++, Win7, __asm вставки (процессор Pentium)
Сообщение18.03.2013, 00:42 


05/09/12
2587
Вы намекаете на то, что компилятор вставляет в начало и конец функции сохранение/восстановление контекста из стека и от этого сбивается адрес возврата? Скорее всего вы правы, я сейчас попробую найти как в Студии посмотреть скомпилированный код, и если найду - выложу сюда.

 Профиль  
                  
 
 Re: С++, Win7, __asm вставки (процессор Pentium)
Сообщение18.03.2013, 00:43 
Заслуженный участник
Аватара пользователя


06/10/08
6422
_Ivana в сообщении #697373 писал(а):
Вы намекаете на то, что компилятор вставляет в начало и конец функции сохранение/восстановление контекста из стека и от этого сбивается адрес возврата? Скорее всего вы правы, я сейчас попробую найти как в Студии посмотреть скомпилированный код, и если найду - выложу сюда.
Скорее всего, какая-нибудь такая ерунда. У меня просто нет Windows дома, я сам посмотреть не могу.

 Профиль  
                  
 
 Re: С++, Win7, __asm вставки (процессор Pentium)
Сообщение18.03.2013, 00:49 


05/09/12
2587
Даже если так, то остается вопрос - как мне красиво оформить многочисленные вызовы нескольких одних и тех же операций с единственным регистром - без сохранения всего окружающего контекста в стеке. Я думал про макрос, но тоже как-то не оптимально, да и не получилось навскидку.
ЗЫ в чистом asm у меня таких проблем не возникало, там никто не пытался втайне от меня спасать контекст в стек при RCALL - RET, и получались лаконичные вещи. Неужели во вставках в C++ нет хороших вариантов для этого?

 Профиль  
                  
 
 Re: С++, Win7, __asm вставки (процессор Pentium)
Сообщение18.03.2013, 00:51 
Заслуженный участник
Аватара пользователя


06/10/08
6422
Я бы сделал макрос. Почему Вы думаете, что это неоптимально?

 Профиль  
                  
 
 Re: С++, Win7, __asm вставки (процессор Pentium)
Сообщение18.03.2013, 00:56 


05/09/12
2587
Если вызов функции однозначно тянет за собой сохранение всего контекста, то макрос конечно лучше - и быстрее, никаких лишних операций. Просто у меня с микроконтроллеров осталась привычка экономить флеш и озу по максимуму - а макросы неоптимально увеличивают размер кода во флеш. В этом смысле чисто ассемблерные вызовы функций без сохранения контекста были оптимальным компромиссом, хотя и требовали несколько лишних тактов на вызов/возврат по сравнению с макросами.

-- 18.03.2013, 01:16 --

Нашел листинг - увидел много нового и интересного :-) Не думал, что мои простые операции компилятор будет окружать таким.... вниманием :-)
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
void expand_CL(void)
{
004BCDB0  push        ebp  
004BCDB1  mov         ebp,esp
004BCDB3  sub         esp,0C0h
004BCDB9  push        ebx  
004BCDBA  push        esi  
004BCDBB  push        edi  
004BCDBC  lea         edi,[ebp-0C0h]
004BCDC2  mov         ecx,30h
004BCDC7  mov         eax,0CCCCCCCCh
004BCDCC  rep stos    dword ptr es:[edi]
        __asm{
                AND CL, BIN8(00000111)
004BCDCE  and         cl,7
                CMP CL, 3
004BCDD1  cmp         cl,3
                JB M1
004BCDD4  jb          M1 (4BCDD8h)
                INC CL
004BCDD6  inc         cl  
M1:             CMP CL, 7
004BCDD8  cmp         cl,7
                JB M2
004BCDDB  jb          M2 (4BCDDFh)
                INC CL
004BCDDD  inc         cl  
M2:                            
                //POP         <registers>   //; Restore registers
                //MOV         esp, ebp      //; Restore stack pointer
                //POP         ebp           //; Restore ebp
                //RET                       //; Return from function           
                RET
004BCDDF  ret              
        }
}
004BCDE0  pop         edi  
004BCDE1  pop         esi  
004BCDE2  pop         ebx  
004BCDE3  add         esp,0C0h
004BCDE9  cmp         ebp,esp
004BCDEB  call        @ILT+36925(__RTC_CheckEsp) (4B1042h)
004BCDF0  mov         esp,ebp
004BCDF2  pop         ebp  
004BCDF3  ret

 Профиль  
                  
 
 Re: С++, Win7, __asm вставки (процессор Pentium)
Сообщение18.03.2013, 01:32 
Заслуженный участник
Аватара пользователя


06/10/08
6422
Да, в таком случае определнно стоит убрать свой RET :)

-- Пн мар 18, 2013 02:36:59 --

_Ivana в сообщении #697386 писал(а):
Если вызов функции однозначно тянет за собой сохранение всего контекста, то макрос конечно лучше - и быстрее, никаких лишних операций. Просто у меня с микроконтроллеров осталась привычка экономить флеш и озу по максимуму - а макросы неоптимально увеличивают размер кода во флеш. В этом смысле чисто ассемблерные вызовы функций без сохранения контекста были оптимальным компромиссом, хотя и требовали несколько лишних тактов на вызов/возврат по сравнению с макросами.
У Вас функция expand_CL будет часто использоваться? если она используется только в паре-тройке других функций, то реализация макросом даст малое увеличение размера программы.

 Профиль  
                  
 
 Re: С++, Win7, __asm вставки (процессор Pentium)
Сообщение18.03.2013, 01:37 


05/09/12
2587
Убрал, позволил процедуре завершаться по своему RETу, вылетать перестала, но зато делает ошибки (по сравнению с тем, если этот же код дублировать прямо в вызывающей функции). Видимо, содержимое регистра не сохраняется в нем самом, или ещё что... Придется либо макрос побеждать, либо как-нибудь научить компилятор не делать всего вышесозданного :-)

Вы правы, она используется в тройке мест всего... Я уже склоняюсь к макросу, особенно после увиденного :-) Если, конечно, внутри asm вставки я не смогу создать подфункцию (что вряд ли) или как-нибудь ещё сделать вызов без таких обрамлений.

 Профиль  
                  
 
 Re: С++, Win7, __asm вставки (процессор Pentium)
Сообщение18.03.2013, 01:41 
Заслуженный участник
Аватара пользователя


06/10/08
6422
_Ivana в сообщении #697399 писал(а):
Убрал, позволил процедуре завершаться по своему RETу, вылетать перестала, но зато делает ошибки (по сравнению с тем, если этот же код дублировать прямо в вызывающей функции). Видимо, содержимое регистра не сохраняется в нем самом, или ещё что...
Из-за этого:
Цитата:
004BCDC2 mov ecx,30h
. CL это же часть ECX. Другое дело, что я пока не понимаю, что он там делает и зачем.

 Профиль  
                  
 
 Re: С++, Win7, __asm вставки (процессор Pentium)
Сообщение18.03.2013, 01:43 


05/09/12
2587
Действительно :-) Чудны дела его....

 Профиль  
                  
 
 Re: С++, Win7, __asm вставки (процессор Pentium)
Сообщение18.03.2013, 01:53 
Заслуженный участник
Аватара пользователя


06/10/08
6422
Вот, я нашел, как это выключить: Тыц

-- Пн мар 18, 2013 03:01:04 --

Однако.
Цитата:
This code is emitted due to the /RTC compile option. It initializes all local variables in your function to a bit pattern that is highly likely to generate an access violation or to cause unusual output values. That helps you find out when you forgot to initialize a variable.
Эта штука делается для того, чтобы если Вы забыли инициализировать локальные переменные (несмотря на то, что их нет), мы бы получили ерунду.

 Профиль  
                  
 
 Re: С++, Win7, __asm вставки (процессор Pentium)
Сообщение18.03.2013, 02:04 


05/09/12
2587
Какое Вам спасибо :-) Значит можно все-таки делать просто и лаконично. А в той книжке, которую я читаю, об этой директиве ни слова, и даже примеры кода приведены без нее...
код: [ скачать ] [ спрятать ]
Используется синтаксис ASM
__declspec( naked ) void expand_CL(void)
{       __asm{
                AND CL, BIN8(00000111)
004BCDB0  and         cl,7
                CMP CL, 3
004BCDB3  cmp         cl,3
                JB M1
004BCDB6  jb          M1 (4BCDBAh)
                INC CL
004BCDB8  inc         cl  
M1:             CMP CL, 7
004BCDBA  cmp         cl,7
                JB M2
004BCDBD  jb          M2 (4BCDC1h)
                INC CL
004BCDBF  inc         cl  
M2:             RET
004BCDC1  ret


ЗЫ а с предопределением регистров действительно интересный момент :-)

 Профиль  
                  
 
 Re: С++, Win7, __asm вставки (процессор Pentium)
Сообщение18.03.2013, 04:03 
Заслуженный участник


09/09/10
3729

(Оффтоп)

Увы, пора ассемблерных вставок на x86/x6-64 давно прошла...

 Профиль  
                  
 
 Re: С++, Win7, __asm вставки (процессор Pentium)
Сообщение18.03.2013, 10:49 
Заслуженный участник


28/04/09
1933

(Joker_vD)

Joker_vD в сообщении #697421 писал(а):
Увы, пора ассемблерных вставок на x86/x6-64 давно прошла...
С какой стати-то? Для оптимизации быстродействия "узких мест" частенько используются. И не только.

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 18 ]  На страницу 1, 2  След.

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group