Например в некоторой функции Function я хочу в своих собственных целях использовать, скажем, регистр ebx: Код (Text): void Function() { __asm mov ebx,0; //... GetModuleHandle(0); // или ещё какая-нибудь апи... //.. __asm mov eax,ebx; //... } Но при этом я хочу чтобы его значение внутри этой функции всегда оставалось постоянным, то есть чтобы компилятор обходился без него. Возможно ли это сделать?
Quark В случае вызова API ebx esi edi у тебя и так будут нетронутыми. А вот в обычных функциях указать компилятору, чтобы он не трогал регистр, сложновато.
они будут не тронутыми в начале и в конце а в середине вовсе не факт может сразу сказать что никто не знает как и скорее всего никак? зы а зачем это скрещивание вообще нужно?
Не факт. Если в асм-вставке в начале в начале и в конце функции использовать регистр, то, может, компилятор и зарезервирует его. Quark А вообще, проще выделить отдельную переменную и не париться?
Quark AFAIK, если ты в асм-вставках используешь регистр, то компилятор будет избегать его использования для С-кода между этими вставками или, в крайнем случае, сделает push/pop. Asterix +1. Лучше использовать отдельные асм-файлы.
Можно попробовать так: _asm{ ;use reg0 ... push reg0 } //SomeAPI(args); _asm{ pop reg0; или xchg [esp],reg0 ... ;если было xchg [esp],reg0 , то ещё раз } Но не факт, что компилятор не изменял esp между вставками. Проще между вызовами сохранять регистр в переменную. Или писать SomeAPI(args); как push args->call SomeAPI, ну и если надо, то восстанавливать esp.
Спасибо за ответы. Вот только я не спрашивал про целесообразность использования ассемблерных вставок. То что АПИ ebx esi edi не трогает это известно. Дело тут в другом. если я хочу писать базонезависимый код на СИ - могу ли я зарезервировать ebx и хранить там базовый адрес. и при этом быть уверенным что система не тронет его... Просто иногда влом писать на ассемблере инжектируемый код. Есть ли какие-то соображения по адресации статических данных в VC? хранить указатель на базу в отдельной переменной - это не выход. слишком много операций разименования. Что если завести переменную-указатель следующим образом: register PVOID Base;?
Вобщем можно просто не объявлять статические переменные. Все строки, если они будут, заполнять динамически.
Quark Если мы такие продвинутые хакеры, что даже про "АПИ ebx esi edi не трогает" давно знаем и вообще Может быть, пора разобраться с тем, что из себя представляют локальные переменные в плане каких-либо зависимостей от базы? Гениально. Так база нужна была только для получения адреса каких-то строк? Цирк!
При чём тут получение адресов..? Про регистры я сказал только потому что чел вопрос не понял. мне пофиг на АПИ, мне нужно чтобы сам компилятор регистр не трогал и не изменял его значение. чтобы я в любом месте функции мог сделать ассемблерную вставку и обратиться к этому регистру. Что касается базонезависимого кода. Если мне позарез в коде нужны строки - что мне все их заполнять динамически? ладно если в строке 8-10 символов - можно и за 3 операции сделать. а если в строке 50 символов... Код (Text): char str[50]; *(PDWORD)&str[0] = 'dcba'; *(PDWORD)&str[4] = 'hgfe'; ... вот и посмотри как страдает качество кода. Что-то я не понимаю - чему ты удивляешься? я просто говорю об оптимизации. говорю что выгодней объявлять статические данные, а потом просто адресовать их относительно базы. Если просто объявить указатель, то компилятор наверняка выделит под него место в стеке (хоть он и пытается в целях оптимизации резервировать регистры под указатели - у него это не всегда получается) и получится что для адресации переменных компилятору нужно будет делать ещё одну операцию разименования. Вот и нужно завести регистровый указатель и адресовать относительно него. Но проблемма в том, чо компилятор просто так регистр в моё пользование не отдаст - он будет использовать его для своих нужд. Что непонятного в вопросе?
Есть только один способ - написать всю процедуру на асме. Компилятор не может знать о том, что хотел сделать программист в ассемблерных вставках.
halyavin Вменяемый компилятор, даже многажды проклятый MSVC не только может, но еще и очень даже догадывается, по крайней мере в плане использования регистров. Я даже как-то здорово повеселился, когда обнаружил, что он очень даже знает, что RDTSC портит EAX и EDX