2014 dxdy logo

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

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




На страницу 1, 2  След.
 
 С++, Win7, __asm вставки (процессор Pentium)
Сообщение17.03.2013, 23:53 
Пишу в вижуал Студии, делаю ассемблерные вставки, хочу вызывать си-процедуру, в которой тоже ассемблер - просто поменять значение одного регистра, не хочу никаких стеков, ОЗУ и прочего. При выходе похоже не восстанавливается из стека адрес возврата и программа вылетает. Подскажите, где ошибка? (Лишние куски кода убрал для краткости)
код: [ скачать ] [ спрятать ]
Используется синтаксис 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 
Аватара пользователя
А Вы можете сгенерированный компилятором ассемблерный код показать?

 
 
 
 Re: С++, Win7, __asm вставки (процессор Pentium)
Сообщение18.03.2013, 00:42 
Вы намекаете на то, что компилятор вставляет в начало и конец функции сохранение/восстановление контекста из стека и от этого сбивается адрес возврата? Скорее всего вы правы, я сейчас попробую найти как в Студии посмотреть скомпилированный код, и если найду - выложу сюда.

 
 
 
 Re: С++, Win7, __asm вставки (процессор Pentium)
Сообщение18.03.2013, 00:43 
Аватара пользователя
_Ivana в сообщении #697373 писал(а):
Вы намекаете на то, что компилятор вставляет в начало и конец функции сохранение/восстановление контекста из стека и от этого сбивается адрес возврата? Скорее всего вы правы, я сейчас попробую найти как в Студии посмотреть скомпилированный код, и если найду - выложу сюда.
Скорее всего, какая-нибудь такая ерунда. У меня просто нет Windows дома, я сам посмотреть не могу.

 
 
 
 Re: С++, Win7, __asm вставки (процессор Pentium)
Сообщение18.03.2013, 00:49 
Даже если так, то остается вопрос - как мне красиво оформить многочисленные вызовы нескольких одних и тех же операций с единственным регистром - без сохранения всего окружающего контекста в стеке. Я думал про макрос, но тоже как-то не оптимально, да и не получилось навскидку.
ЗЫ в чистом asm у меня таких проблем не возникало, там никто не пытался втайне от меня спасать контекст в стек при RCALL - RET, и получались лаконичные вещи. Неужели во вставках в C++ нет хороших вариантов для этого?

 
 
 
 Re: С++, Win7, __asm вставки (процессор Pentium)
Сообщение18.03.2013, 00:51 
Аватара пользователя
Я бы сделал макрос. Почему Вы думаете, что это неоптимально?

 
 
 
 Re: С++, Win7, __asm вставки (процессор Pentium)
Сообщение18.03.2013, 00:56 
Если вызов функции однозначно тянет за собой сохранение всего контекста, то макрос конечно лучше - и быстрее, никаких лишних операций. Просто у меня с микроконтроллеров осталась привычка экономить флеш и озу по максимуму - а макросы неоптимально увеличивают размер кода во флеш. В этом смысле чисто ассемблерные вызовы функций без сохранения контекста были оптимальным компромиссом, хотя и требовали несколько лишних тактов на вызов/возврат по сравнению с макросами.

-- 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 
Аватара пользователя
Да, в таком случае определнно стоит убрать свой RET :)

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

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

 
 
 
 Re: С++, Win7, __asm вставки (процессор Pentium)
Сообщение18.03.2013, 01:37 
Убрал, позволил процедуре завершаться по своему RETу, вылетать перестала, но зато делает ошибки (по сравнению с тем, если этот же код дублировать прямо в вызывающей функции). Видимо, содержимое регистра не сохраняется в нем самом, или ещё что... Придется либо макрос побеждать, либо как-нибудь научить компилятор не делать всего вышесозданного :-)

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

 
 
 
 Re: С++, Win7, __asm вставки (процессор Pentium)
Сообщение18.03.2013, 01:41 
Аватара пользователя
_Ivana в сообщении #697399 писал(а):
Убрал, позволил процедуре завершаться по своему RETу, вылетать перестала, но зато делает ошибки (по сравнению с тем, если этот же код дублировать прямо в вызывающей функции). Видимо, содержимое регистра не сохраняется в нем самом, или ещё что...
Из-за этого:
Цитата:
004BCDC2 mov ecx,30h
. CL это же часть ECX. Другое дело, что я пока не понимаю, что он там делает и зачем.

 
 
 
 Re: С++, Win7, __asm вставки (процессор Pentium)
Сообщение18.03.2013, 01:43 
Действительно :-) Чудны дела его....

 
 
 
 Re: С++, Win7, __asm вставки (процессор Pentium)
Сообщение18.03.2013, 01:53 
Аватара пользователя
Вот, я нашел, как это выключить: Тыц

-- Пн мар 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 
Какое Вам спасибо :-) Значит можно все-таки делать просто и лаконично. А в той книжке, которую я читаю, об этой директиве ни слова, и даже примеры кода приведены без нее...
код: [ скачать ] [ спрятать ]
Используется синтаксис 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 

(Оффтоп)

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

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

(Joker_vD)

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

 
 
 [ Сообщений: 18 ]  На страницу 1, 2  След.


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group