C++ Builder Assembler

Тема в разделе "WASM.ASSEMBLER", создана пользователем RabiatoR, 1 июл 2010.

  1. RabiatoR

    RabiatoR Влад

    Публикаций:
    0
    Регистрация:
    12 янв 2010
    Сообщения:
    5
    Адрес:
    Красноярск
    Народ помоги пожалуйста, у меня возникла такая проблемка, использую я Codegear RAD Studio C++ Builder
    Создал новое Console Apllication с параметрами: Console Application - false, MultiThreaded - true, Include VCL - false
    Пишу в ней код:

    Код (Text):
    1. void GETCPUID( void ){__asm{
    2.     PUSH EBP
    3.     MOV EBP, ESP
    4.     XOR ECX, ECX
    5.     PUSH ECX
    6.     XOR EAX, EAX
    7.     PUSH EBP
    8.     PUSH OFFSET @@2
    9. @@1:
    10.     CPUID
    11.     MOV EBP, EAX
    12. @@2:
    13.     MOV AL, [EBP-1]
    14.     MOV ESP, EBP
    15.     POP EBP
    16.     RETN
    17. }}
    Возникает ошибка компиляции:
    Undefined Symbol: '@@2'
    на строке PUSH OFFSET @@2
    Как с этим справится?
     
  2. kweed

    kweed New Member

    Публикаций:
    0
    Регистрация:
    17 июн 2009
    Сообщения:
    81
    может здесь что-то есть:
     
  3. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Не знаю как в старших версиях, но, например, билдер 6 в упор не воспринимает никаких операций взятия\получения адресов локальных меток - только джампы и колы, и ничего более

    Конечно не понятно нафига в приведенном коде вообще нужны и пуши, и метки, но там где действительно нужно получить адрес метки можно извратиться путем объявления асм-функций не в cpp-модуле, а в pas, т.к. все билдеры без проблем компилируют pas в hpp\cpp
     
  4. RabiatoR

    RabiatoR Влад

    Публикаций:
    0
    Регистрация:
    12 янв 2010
    Сообщения:
    5
    Адрес:
    Красноярск
    а не подскажеш как это сделать? я просто этот код ввиде примера привел.
    да и вообще он ругается на "proc near", пришлось выводить в "void ?( void ){__asm{" как вы заметили :)
    Я просто незнаю как метки обьявлять, да ещо и к тому же с pas файлами)
     
  5. RabiatoR

    RabiatoR Влад

    Публикаций:
    0
    Регистрация:
    12 янв 2010
    Сообщения:
    5
    Адрес:
    Красноярск
    Дело в том, что JMP инструкция нормально воспринимает метки, а вот PUSH инструкция выдает такое сообщение об ошибке!
     
  6. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Ну а я тебе что говорил - "только джампы и колы, и ничего более" ?!
    Такой вот "кастрированный" асм в билдере ;) Поэтому для получения адреса метки остается либо прикручивать извращения со стандартным call+pop:
    Код (Text):
    1. int MyTest_Cpp(void) {
    2. __asm{
    3.   call @@2
    4. @@2:
    5.   pop eax}}
    либо с модулем на паскале, в котором нет этих дурных ограничений:
    Код (Text):
    1. //--- модуль MyPasUnit.pas ---
    2. unit MyPasUnit;
    3. interface
    4. function MyTest_Pas:integer;
    5. implementation
    6.  
    7. function MyTest_Pas:integer;
    8. asm
    9.   push offset @@2
    10. @@2:
    11.   pop eax
    12. end;
    13.  
    14. end.
    15. //----------------------
    16.  
    17. //--- сишный модуль ---
    18. #include "MyPasUnit.hpp"
    19.  
    20. int MyTest_Cpp(void) {
    21.   return MyTest_Pas();
    22. }
     
  7. RabiatoR

    RabiatoR Влад

    Публикаций:
    0
    Регистрация:
    12 янв 2010
    Сообщения:
    5
    Адрес:
    Красноярск
    Спасибо, через pas модуль действительно всё работает :) но у меня новый вопрос на ту же тему:
    я создал файл test.asm
    Код (Text):
    1. .686p
    2. .mmx
    3. .model flat
    4.  
    5. .data
    6.         Var1 dd 0
    7.  
    8. .code
    9.  
    10. _TEXT SEGMENT DWORD PUBLIC USE32 'CODE'
    11.         PUBLIC C UserExtraInfo
    12.         $UserExtraInfo SEGMENT VIRTUAL
    13.                 UserExtraInfo PROC C
    14.                 @Begin:
    15.                         PUSH EBP
    16.                         MOV EBP, ESP
    17.                         MOV EAX, OFFSET Var1
    18.                         MOV EDX, [EBP+8]
    19.                         MOV ECX, 0
    20.                         SLDT AX
    21.                 @End:
    22.                         POP EBP
    23.                         RET 4
    24.                 ENDP
    25.         $UserExtraInfo ENDS
    26. _TEXT ENDS
    27.  
    28. end
    подключил его к проекту, в С++ написал
    Код (Text):
    1. extern "C" void UserExtraInfo( void );
    При компиляции линкер выдаёт:
    я убрал из С++ вызов даннной функции, откомпилил, и через ollydbg просмотрел результат, в нем нет кода из test.asm, как правильно подключать .asm файлы и использовать функции описаные в них?