передача массива из Си в Ассемблер

Тема в разделе "LANGS.C", создана пользователем Dmitriy_M, 1 май 2009.

  1. Dmitriy_M

    Dmitriy_M New Member

    Публикаций:
    0
    Регистрация:
    1 май 2009
    Сообщения:
    4
    Код (Text):
    1. #include <iostream>
    2.  
    3. using namespace std;
    4.  
    5.  
    6. extern "C" void TestProc(int n, char* mas);
    7.  
    8. int main(void)
    9. {
    10.     char* arr="Hello World";
    11.     int a=11;
    12.     TestProc(a,arr);
    13.     return 0;
    14. }
    Код (Text):
    1. .486
    2. .MODEL FLAT,STDCALL
    3. OPTION CASEMAP:NONE
    4.  
    5. .CODE
    6.  
    7.     TestProc PROC C size_array:DWORD, ptr_array:DWORD
    8.     mov edi, ptr_array
    9.     mov [edi], 35h
    10.     ret          
    11.     TestProc ENDP
    12. END
    MASM на строчку mov [edi], 35h выдает modul.asm(9) : error A2070: invalid instruction operands
    Вопрос: как правильно получить адрес массива, чтобы с ним работать?
     
  2. ohne

    ohne New Member

    Публикаций:
    0
    Регистрация:
    28 фев 2009
    Сообщения:
    431
    Код (Text):
    1. _TestProc
    ?
    Код (Text):
    1. mov byte ptr[edi], 35h
    2. mov word ptr[edi], 35h
    3. mov dword ptr[edi], 35h
    какой конкретно вариант нужен?
     
  3. ohne

    ohne New Member

    Публикаций:
    0
    Регистрация:
    28 фев 2009
    Сообщения:
    431
    да уж, а редактирования все нет ... =/
     
  4. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Во-первых, когда пишешь константу в память всегда нужно явно указывать размер области памяти byte ptr [edi] и т.п. (т.к. компилятор понятия не имеет, хочешь ли ты записать 35h байт, ворд или дворд)
    Во-вторых, по общему соглашению о вызовах процедуры\функции могут свободно изменять только регистры eax, edx и ecx, а остальные (ebx,ebp,edi,esi) не должны изменяться - в сл.необходимости их нужно сохранять на входе и восстанавливать на выходе из процедуры (или в масме юзать uses edi)
    В-третьих, в сишном коде объявления TestProc не мешало бы добавить stdcall
     
  5. Dmitriy_M

    Dmitriy_M New Member

    Публикаций:
    0
    Регистрация:
    1 май 2009
    Сообщения:
    4
    понятно. Вроде как extern "C" заставляет использовать sdtcall.
    С таким примером
    Код (Text):
    1.    
    2. TestProc PROC C size_array:DWORD, ptr_array:DWORD
    3.     mov ebx, ptr_array
    4.     mov byte ptr [ebx], 35h
    5.     ret          
    6.     TestProc ENDP
    собираться, но при запуске вылетает.
     
  6. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Dmitriy_M
    В сях не силен, но extern "C" вроде как просто не позволяет манглить имена, т.е. дописывать к ним всякте бяки ;)

    "Заболели - полячитеся" (С) :lol:
    Использовать eax, вместо ebx - не судьба или религия не позволяет ? Ясно же было сказано:
     
  7. Dmitriy_M

    Dmitriy_M New Member

    Публикаций:
    0
    Регистрация:
    1 май 2009
    Сообщения:
    4
    Стал использовать eax. В описал процедуру extern "C" void __stdcall TestProc(char* mas);
    Добавил опцию для g++ -enable-stdcall-fixup.
    Все равно вылетает на mov byte ptr [eax], 35h
    Возврат массива работает
    Код (Text):
    1. .586
    2. .MODEL FLAT,STDCALL
    3. OPTION CASEMAP:NONE
    4. .CODE
    5.  
    6.     TestProc PROC C ptr_array:DWORD
    7.     mov eax, ptr_array
    8.     lea eax, message
    9.     ret          
    10.     TestProc ENDP
    11. .DATA
    12. message db "Hello World"
    Сложение двух чисел то же работает
    Код (Text):
    1.     TestProc PROC C par1:DWORD, par2:DWORD
    2.     mov eax, par1
    3.     add eax, par2
    4.     ret          
    5.     TestProc ENDP
    А с массивом не получается.
     
  8. leo

    leo Active Member

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

    Dmitriy_M New Member

    Публикаций:
    0
    Регистрация:
    1 май 2009
    Сообщения:
    4
    leoпремного благодарен, за то что указали на мои глупые ошибки.