На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Перед отправкой сообщения внимательно прочтите правила раздела!!!
1. Запрещается обсуждать написание вирусов, троянов и других вредоносных программ!
2. Помните, что у нас есть FAQ раздела Assembler и Полезные ссылки. Посмотрите, возможно, там уже имеется решение вашего вопроса.

3. Настоятельно рекомендуем обратить особое внимание на правила форума, которые нарушаются чаще всего:
  3.1. Заголовок темы должен кратко отражать её суть. Темы с заголовками типа "Срочно помогите!" или "Ассемблер" будут отправляться в Корзину для мусора.
  3.2. Исходники программ обязательно выделяйте тегами [code]...[/code] (одиночные инструкции можно не выделять).
  3.3. Нежелательно поднимать старые темы (не обновлявшиеся более года) без веской на то причины.

Не забывайте также про главные Правила форума!

Добро пожаловать и приятного вам общения!!! ;)
 
Модераторы: Jin X, Qraizer
  
> компиляция одного исходника под 32 и 64 , masm, defines, visual studio
    Портировал на ассемблер один проект из Delphi (1500 строк), компилирую его из Visual Studio с помощью masm. В среде выбрал соотв. опции (Build Dependencies -> masm) и в опциях проекта Microsoft Macro Assembler. Под 32 работает. Теперь хочу портировать код под 64, да так чтобы не писать новый код со всеми особенностями 64 разработки, а прям в этом же файле с условными компиляциями и макроопределениями, к примеру

    ExpandedWrap disabled
      IFDEF RAX
        _WIN64 equ TRUE
      ELSE
        _WIN32 equ TRUE
      ENDIF
       
      IFDEF _WIN32
          .386
          .model flat, stdcall
          option casemap :none   ; case sensitive
       
      include c:\masm32\include\windows.inc
      include c:\masm32\include\kernel32.inc
       
      my_eax equ eax
       
      ELSE
       
      include c:\masm64\include64\win64.inc
      include c:\masm64\include64\kernel32.inc
       
      my_eax equ rax
       
      ENDIF


    1. Если переопределить все регистры.
    2. В участках кода где вызываются функции с помощью условных компиляций выделить место в стеке
    ExpandedWrap disabled
      sub rsp, 32
    и соотв. по завершению обратно вернуть.
    3. Заменить структуры и типы на 64 вариант, где это требуется.
    4. Выровнять границу в нужных местах.
    и т.д.
    Насколько адекватна затея всё это городить в одном файле исходного текста? Дело в том что по определённым причинам нужно именно в одном файле.
    Какие могут быть ещё нюансы, чтобы грамотно всё сделать? Ещё такой вопрос, взял отсюда комплект под 64 и сгенерил либы инклуды Library update May 2018 может это всё не нужно раз из студии компилирую, как через неё можно сгенерировать инклуды и т.д.

    Спасибо!
      kin01, тут зависит от того, что в исходнике и как он написан.
      Теоретически, это возможно (правда, некоторые возможности будут утеряны, например, можно было бы оптимизировать код с учётом наличия r8-r15 и SSE2), а практически все может оказаться сложнее, чем кажется (тем более, если прога длинная).
      Нюансы:
      • Могут поехать размеры данных из-за изменения размеров операндов. К примеру, есть dd и dword ptr. Нужно ли их приводить к dq и qword ptr? Далеко не всегда, зависит от конкретном ситуации. К примеру, в виндовых структурах есть dw-поле, а есть lpsz. Поле dw Всегда будет 32-битным, а lpsz – зависит от разрядности. При этом, если мы записываем что-то с помощью mov dwSomeData,eax, то mov dwSomeData,rax вызовет ошибку. Но тут можно играться с названиями универсальных регистров. Там, где нужно всегда использовать eax, указывать явно: eax. А где операнд зависит от разрядности – my_eax. Аналогично с dd, dword ptr.
      • То же самое, но с непосредственными значениями. Что значит 0FFFF0000h? Что у нас только 16 младших разрядов должны быть обнулены или что старшие 32 (в 64 битах) тоже?
      • Как сделаны вызовы и объявления функций? Если это просто метки и push+call, то будет геморно (потому как фреймы устроены по-разному, да и параметры передаются по-разному). Тут sub rsp,32 может оказаться недостаточно, т.к. нужно выравнивать стек до 8 байт. Но если через invoke/proc, тогда всё должно работать само собой. Но! Вызов invoke SomeFunc, eax, ecx сработает в Win32, а вот в Win64 (invoke SomeFunc, rax, rcx) – не факт, т.к. invoke скорее всего заносит в регистры-параметры данные тупо последовательно (у меня именно такой вариант, по приведённой вами ссылке – не знаю, может, там исправлено), т.е. это развернётся в:
      ExpandedWrap disabled
        mov rcx,rax
        mov rdx,rcx  ; опа... а rcx у нас уже перезаписан!
        call [Function]
      • Если есть push/pop, которые окружают вызов функции, они могут нарушить выравнивание стека перед вызовом (т.к. это не учитывается при создании фрейма).
      • Если вдруг в коде используются инструкции, которые в 64-х битах недоступны (скажем, das, например, для перевода в 16-ричное число), то этот кусок кода придётся переписывать.
      • Ну и пр., о чём я ещё не вспомнил.
      Пробуйте. Всё реально :)

      Добавлено
      Цитата kin01 @
      Ещё такой вопрос, взял отсюда комплект под 64 и сгенерил либы инклуды Library update May 2018 может это всё не нужно раз из студии компилирую, как через неё можно сгенерировать инклуды и т.д.
      Думаю, что нужно, т.к. когда я делал подобное, я не нашёл у себя файла, к примеру, kernel32.inc и пр., и брал из masm32 и стороннего комплекта под ml64.

      Добавлено
      По трудоёмкости сложно сказать, всё сильно зависит от кода. Может, он там так написан, что проще сделать
      ExpandedWrap disabled
        if _WIN32
          ; весь код под 32
        elseif _WIN64
          ; весь код под 64
        endif
      :)

      Добавлено
      Посмотрел вашу ссылку. А что там, собственно, ценного? Это чисто библиотека m64lib, там нет inc'ов вообще. Вам надо вот это: http://xk8.ru/ml64
        не то скопировал. ниже по ссылке есть makeall.bat который всё делает.
        Current build of the 64 bit MASM SDK

        Добавлено
        но по сути нужны только *.inc т.к. в студии всё есть.
          Оказалось достаточно легко написать исходный код для двух платформ. Помимо переопределения регистров:

          ExpandedWrap disabled
                rax equ eax
                rcx equ ecx
                rdx equ edx
                rbx equ ebx
                rbp equ ebp
                rsp equ esp
                rsi equ esi
                rdi equ edi
                r9  equ ebx
                r8d equ ebx
                r8b equ bl
                r8  equ ebx


          переопределил типы, структуры
          ExpandedWrap disabled
            Pointer         typedef PVOID;
            NativeInt       typedef SIZE_T;
            UIntPtr         typedef SIZE_T
            HINST           typedef SIZE_T;
            Integer         typedef DWORD;
            TMemoryModule   typedef Pointer;
            Cardinal        typedef Integer;
            PUINT16         typedef PTR UINT16;
            PUINT_PTR       typedef PTR UINT_PTR
            PPointer        typedef PTR Pointer
            PWord           typedef PTR Word
            PAnsiChar       typedef Pointer
            PByte           typedef Pointer


          и использовал несколько макросов
          ExpandedWrap disabled
            ;--------------------------------------------
            ;               CROSS
            ;--------------------------------------------
             
              pmx macro arg1, arg2
                ifdef win32
                    push arg2
                else
                    mov arg1, arg2
                endif
              endm
              
              plx macro arg1, arg2
                ifdef win32
                    lea arg1, arg2
                    push arg1
                else
                    lea arg1, arg2
                endif
              endm
             
              CROSS_MOVSXD macro arg1, arg2
                IFDEF win64
                    movsxd arg1, arg2
                ELSE
                    mov arg1, arg2
                ENDIF
              ENDM


          получилось нечто такого
          ExpandedWrap disabled
                pmx rdx, rdx
                mov rax, codebase
                mov rcx, section
                mov ecx, (IMAGE_SECTION_HEADER ptr [rcx]).VirtualAddress
                add rcx, rax
                pmx rcx, rcx
                call VirtualAlloc


          почти нет условных компиляций в коде. только в препроцессоре.
          0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
          0 пользователей:


          Рейтинг@Mail.ru
          [ Script execution time: 0,0427 ]   [ 15 queries used ]   [ Generated: 28.03.24, 10:42 GMT ]