Вызов оператора new[] из вставки asm

Тема в разделе "WASM.BEGINNERS", создана пользователем Engineer, 19 сен 2006.

  1. Engineer

    Engineer New Member

    Публикаций:
    0
    Регистрация:
    11 сен 2006
    Сообщения:
    7
    Приветствую. Прошу помочь разобраться со следующей проблемой: в коде на bс6 есть вставка asm где требуется вызвать оператор выделения памяти кучи, делаю так:
    ...
    asm push 1024
    asm call new
    ...
    вызывается new, а не new[](естественно написать call new[] -невозможно). Как вдолбить компилятору(встроенному асму), что от него хотят? Спасибо.
     
  2. halyavin

    halyavin New Member

    Публикаций:
    0
    Регистрация:
    13 май 2005
    Сообщения:
    252
    Адрес:
    Russia
    В си++ не предусмотрена работа с объектами из ассемблерных вставок. Это можно делать (насколько мне известно) только в дельфи. Поэтому тебе придется в этом месте вызвать сишную функцию-переходник, которая и выполнит new или неиспользовать ассемблерную вставку в этом месте вообще.
     
  3. Engineer

    Engineer New Member

    Публикаций:
    0
    Регистрация:
    11 сен 2006
    Сообщения:
    7
    Ну с объектами можно, -тут просто путаница с адресом вызываемой функции выходит т.е. org new <-> org new[]. asm call new -проходит, а написать asm call new[] -Invalid opcode and operand size. Конечно мне проще вызвать malloc по идее(все равно нужен массив чаров под строку). Но asm call offset malloc -вообще выдает internal linker error.
     
  4. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Engineer
    Если это вставка, то что мешает вызвать вне её?
    __asm ...
    p = new char[1024]
    __asm ...
     
  5. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    а что мешает сделать, как в посте #2?
     
  6. Engineer

    Engineer New Member

    Публикаций:
    0
    Регистрация:
    11 сен 2006
    Сообщения:
    7
    To IceStudent&nOname:

    мешает... не поверите. Вид генерящегося кода, как известно p=new char[size] (или при вызове функции адаптера к оператору new[])
    превращяется в:
    push size
    call new\malloc\xyz( !!! стоит просто оффсет -что правильно и без извращений как ниже !!! )
    pop _ненужный регистр

    и этот pop reg -все портит... А именно оптимизация и спариваемость с соседними коммандами :dntknw:

    Надо:
    push size
    call new\malloc\xyz
    push eax ;возвращаемый адрес

    единственное до чего я додумался это взять пойнтер на malloc(например заранее) т.е.

    void*(*pmalloc)(uint) =malloc;
    ...
    mov ecx,pmalloc
    push size
    call ecx
    push eax
    ...

    но бесит, факт, что можно в идеале call offset делать...
     
  7. masquer

    masquer wasm.ru

    Публикаций:
    0
    Регистрация:
    13 сен 2002
    Сообщения:
    890
    Адрес:
    Николаев
    какой кошмар! производительность, поди, раз в 50 упала, да?
     
  8. Engineer

    Engineer New Member

    Публикаций:
    0
    Регистрация:
    11 сен 2006
    Сообщения:
    7
    Ну к чему этот сарказм? -Нет, на 1 тик :) А самое главное не красиво стало... И самому как то не приятно, -не первый день кодишь, и такой... кошмар -не можешь красиво перебороть компилятор с его бзиком. Заказчику конечно все равно до кодов, тиков, и т.п. -А мы зачем здесь собрались? Верно?
     
  9. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Engineer
    Ты не там оптимизируешь.
     
  10. Engineer

    Engineer New Member

    Публикаций:
    0
    Регистрация:
    11 сен 2006
    Сообщения:
    7
    Хм. Знаю, что это не критическое место, -вызов "чужой" фунции всего лишь. Вокруг этого new все меня устраивает, а это место прям... кровь к глазам приливает, надо отдохнуть что ли :)
     
  11. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    Engineer
    Я что-то не понял про бзик... ты типа хочешь отложить чистку стека после вызова new в своей асм вставке?
    Если так, то нет проблем:
    Код (Text):
    1. __asm
    2. {
    3. ...
    4. // готовишь стек для вызова new наиболее оптимальным для тебя способом:
    5.     push 1024 // push reg и т.п.
    6. }
    7. ((size_t(*)())operator new)();
    8. __asm
    9. {
    10. // результат в eax
    11. ...
    12. }
    IMHO, все это извращения. Лучше писать асм-код в отдельном асм-файле. Тогда таких проблем не будет.


    Ну так напиши
    Код (Text):
    1. push size
    2. call malloc
    3. push eax
    4. ...
     
  12. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    Воистину. Вообще, Borland'овские компиляторы слабоваты в смысле оптимизации, описаный случа еще не самый жесткий, так что если это критично - лучше посмотреть на другие.
     
  13. Engineer

    Engineer New Member

    Публикаций:
    0
    Регистрация:
    11 сен 2006
    Сообщения:
    7
    call malloc -ошибку на сборке выдает.

    Хе хе Ustus: подозреваю, что bc6 выбран заказчиком из-за наличия vcl :) Однако, он хочет чтобы приложение работало быстрее, чем аналог конкурента, -я сказал, что сделаю и "напичкал" код асм вставками(естественно в критических местах), производительность теперь устраивает всех :) Но юмора borlandюков я не понял. Придется видно жить с pop-ой
     
  14. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Engineer
    Я же говорю, не там оптимизируешь. Можно сделать на порядок быстрее, выбрав правильные алгоритмы. Одними асм-вставками не отделаешься.
     
  15. Ustus

    Ustus New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2005
    Сообщения:
    834
    Адрес:
    Харьков
    А что тут понимать? Вообще-то все верно. Библиотечная malloc - функция, имеющая соглашения вызова __cdecl, поэтому вызывающая функция должна подтереть ей э-э-э... то есть очистить ей стек, занятый при передаче параметров, т. е. если передано двойное слово - выполнить add esp, 4 или pop eblabla. Формально все верно.
     
  16. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Engineer
    Замени pop + push на mov [esp],eax и будет тебе счастье :lol:
    (может даже "полтика" сэкономишь, исключив моп модификации ESP :)))