Приветствую. Прошу помочь разобраться со следующей проблемой: в коде на bс6 есть вставка asm где требуется вызвать оператор выделения памяти кучи, делаю так: ... asm push 1024 asm call new ... вызывается new, а не new[](естественно написать call new[] -невозможно). Как вдолбить компилятору(встроенному асму), что от него хотят? Спасибо.
В си++ не предусмотрена работа с объектами из ассемблерных вставок. Это можно делать (насколько мне известно) только в дельфи. Поэтому тебе придется в этом месте вызвать сишную функцию-переходник, которая и выполнит new или неиспользовать ассемблерную вставку в этом месте вообще.
Ну с объектами можно, -тут просто путаница с адресом вызываемой функции выходит т.е. org new <-> org new[]. asm call new -проходит, а написать asm call new[] -Invalid opcode and operand size. Конечно мне проще вызвать malloc по идее(все равно нужен массив чаров под строку). Но asm call offset malloc -вообще выдает internal linker error.
To IceStudent&nOname: мешает... не поверите. Вид генерящегося кода, как известно p=new char[size] (или при вызове функции адаптера к оператору new[]) превращяется в: push size call new\malloc\xyz( !!! стоит просто оффсет -что правильно и без извращений как ниже !!! ) pop _ненужный регистр и этот pop reg -все портит... А именно оптимизация и спариваемость с соседними коммандами Надо: push size call new\malloc\xyz push eax ;возвращаемый адрес единственное до чего я додумался это взять пойнтер на malloc(например заранее) т.е. void*(*pmalloc)(uint) =malloc; ... mov ecx,pmalloc push size call ecx push eax ... но бесит, факт, что можно в идеале call offset делать...
Ну к чему этот сарказм? -Нет, на 1 тик А самое главное не красиво стало... И самому как то не приятно, -не первый день кодишь, и такой... кошмар -не можешь красиво перебороть компилятор с его бзиком. Заказчику конечно все равно до кодов, тиков, и т.п. -А мы зачем здесь собрались? Верно?
Хм. Знаю, что это не критическое место, -вызов "чужой" фунции всего лишь. Вокруг этого new все меня устраивает, а это место прям... кровь к глазам приливает, надо отдохнуть что ли
Engineer Я что-то не понял про бзик... ты типа хочешь отложить чистку стека после вызова new в своей асм вставке? Если так, то нет проблем: Код (Text): __asm { ... // готовишь стек для вызова new наиболее оптимальным для тебя способом: push 1024 // push reg и т.п. } ((size_t(*)())operator new)(); __asm { // результат в eax ... } IMHO, все это извращения. Лучше писать асм-код в отдельном асм-файле. Тогда таких проблем не будет. Ну так напиши Код (Text): push size call malloc push eax ...
Воистину. Вообще, Borland'овские компиляторы слабоваты в смысле оптимизации, описаный случа еще не самый жесткий, так что если это критично - лучше посмотреть на другие.
call malloc -ошибку на сборке выдает. Хе хе Ustus: подозреваю, что bc6 выбран заказчиком из-за наличия vcl Однако, он хочет чтобы приложение работало быстрее, чем аналог конкурента, -я сказал, что сделаю и "напичкал" код асм вставками(естественно в критических местах), производительность теперь устраивает всех Но юмора borlandюков я не понял. Придется видно жить с pop-ой
Engineer Я же говорю, не там оптимизируешь. Можно сделать на порядок быстрее, выбрав правильные алгоритмы. Одними асм-вставками не отделаешься.
А что тут понимать? Вообще-то все верно. Библиотечная malloc - функция, имеющая соглашения вызова __cdecl, поэтому вызывающая функция должна подтереть ей э-э-э... то есть очистить ей стек, занятый при передаче параметров, т. е. если передано двойное слово - выполнить add esp, 4 или pop eblabla. Формально все верно.
Engineer Замени pop + push на mov [esp],eax и будет тебе счастье (может даже "полтика" сэкономишь, исключив моп модификации ESP ))