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

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

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

Добро пожаловать и приятного вам общения!!! ;)
 
Модераторы: Jin X, Qraizer
  
> затирает локальные переменные , masm64, LOCAL, stack
    Подсмотрел код процедуры в Delphi:

    ExpandedWrap disabled
      procedure br;
      var
        p: pointer;
      begin
        HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, 24);
      end;


    ExpandedWrap disabled
      Project12.dpr.16: begin
      0000000000536660 55               push rbp
      0000000000536661 4883EC30         sub rsp,$30
      0000000000536665 488BEC           mov rbp,rsp
      Project12.dpr.17: HeapAlloc(GetProcessHeap, HEAP_ZERO_MEMORY, 24);
      0000000000536668 E8F348EEFF       call GetProcessHeap
      000000000053666D 4889C1           mov rcx,rax
      0000000000536670 C7C208000000     mov edx,$00000008
      0000000000536676 41C7C018000000   mov r8d,$00000018
      000000000053667D E8AE49EEFF       call HeapAlloc
      Project12.dpr.18: end;
      0000000000536682 488D6530         lea rsp,[rbp+$30]
      0000000000536686 5D               pop rbp
      0000000000536687 C3               ret


    теперь хочу сделать тоже самое в masm

    ExpandedWrap disabled
      include c:\masm32\include64\masm64rt.inc
       
      NOSTACKFRAME
       
      .code
       
      my_test proc
          LOCAL p : QWORD
       
          push rbp
          sub rsp, 30h
          mov rbp, rsp
       
          call GetProcessHeap
          mov rcx, rax
          mov edx, HEAP_ZERO_MEMORY
          mov r8d, 24
          call HeapAlloc
          lea rsp, [rbp + 30h]
          pop rbp
          ret
      my_test endp
       
      main proc
          push rbp
          sub rsp, 50h
              mov rbp, rsp
       
          call my_test
          ret
      main endp
       
      end


    После вызова HeapAlloc в переменную LOCAL p : QWORD попадает мусор. Много читал тем по стеку в win64, но видимо до сих пор что-то не понима. В Delphi может это вообще не процедуры а метки. Пытался и код выровнять в masm. Может это Delphi дизассемблер что-то неправильно показывает?

    Добавлено
    Это резерв для функций которые будут вызыватся в теле основной функции? То есть переменные в masm надо размещать после 32 байт?

    Добавлено
    То есть sub rsp, 30h это под одну локальную переменную + 32 для все вызовов что будут внутри. Плюс иногда возможно нужно выравнивание до 16
      Студия сгенерировала больше места, не считая возврат результата.
      ExpandedWrap disabled
        LPVOID my_alloc()
        {
        000000013F311A50  push        rbp  
        000000013F311A52  push        rdi  
        000000013F311A53  sub         rsp,108h  
        000000013F311A5A  lea         rbp,[rsp+20h]  
        000000013F311A5F  mov         rdi,rsp  
        000000013F311A62  mov         ecx,42h  
        000000013F311A67  mov         eax,0CCCCCCCCh  
        000000013F311A6C  rep stos    dword ptr [rdi]  
            LPVOID i;
         
            return HeapAlloc(GetProcessHeap(), 8, 24);
        000000013F311A6E  call        qword ptr [__imp_GetProcessHeap (013F320000h)]  
        000000013F311A74  mov         r8d,18h  
            LPVOID i;
         
            return HeapAlloc(GetProcessHeap(), 8, 24);
        000000013F311A7A  mov         edx,8  
        000000013F311A7F  mov         rcx,rax  
        000000013F311A82  call        qword ptr [__imp_HeapAlloc (013F320030h)]  
        }
        000000013F311A88  lea         rsp,[rbp+0E8h]  
        000000013F311A8F  pop         rdi  
        000000013F311A90  pop         rbp  
        000000013F311A91  ret


      Добавлено
      Теперь надо понять как грамотно записывать в masm, чтобы был отступ. Не заводить же переменные пустышки для этого.

      Добавлено
      Плюс чтобы стеку программы дали памяти под все переменные в ней.

      Добавлено
      Это задаётся как-то так ?

      ExpandedWrap disabled
        $pdata$my_test DD imagerel my_test
            DD  imagerel my_test+48
            DD  imagerel $unwind$my_test
        Так правильно?
        ExpandedWrap disabled
          include c:\masm32\include64\masm64rt.inc
           
          NOSTACKFRAME
           
          .code
           
          my_test proc
          LOCAL p : QWORD
           
          push rbp
          mov rbp, rsp
          sub rsp, 32 + 8 + 8
           
          call GetProcessHeap
          mov rcx, rax
          mov edx, HEAP_ZERO_MEMORY
          mov r8d, 24
          call HeapAlloc
          add rsp, 32 + 8 + 8
          pop rbp
          ret
          my_test endp
           
          main proc
          push rbp
          sub rsp, 50h
          mov rbp, rsp
           
          call my_test
          ret
          main endp
           
          end


        Добавлено
        поправил на add rsp, 32 + 8 + 8 перед выходом
        Сообщение отредактировано: kin01 -
          Блин, ну вот нету у меня под рукой masmового SDK64.
          kin01, я сильно подозреваю, что дельфийный HeapAlloc() – это совсем не WinAPIховый, а только лишь некий thunk к нему. Посмотри в отладчике дальше, внутрь HeapAlloc(). Почти уверен, в kernel32 ты попадёшь не сразу.
            HeapAlloc в Delphi без обёртки.
            А работа с динамической памятью там вообще идёт без него.
            Тут вообще проблема в другом.

            kin01, с чего вы решили, что локальная переменная p затирается? Если обращаетесь к p через masm64 (вроде mov rax,p), тогда логично, т.к. в первом коде у вас фрейм сделан по странной манере Delphi, а не как положено. Т.е. сначала уменьшается ESP, а затем делается mov ebp,esp. Надо наоборот. В общем-то, как в последнем вашем коде (в процедуре my_test, а в main осталось по-старому).
            Почему положено именно так (почему в Delphi сделано странно)? Потому есть есть инструкции enter и leave специально предназначенные для создания фрейма, и они работают как раз таким образом. Так что, в конце процедуры (перед ret) можно просто поставить leave безо всяких add rsp,... + pop rbp.
            Кстати, почему в main нет эпилога? И ret в конце я бы заменил на invoke ExitProcess, 0 всё-таки (т.к. если вы напишете такую прогу на fasm, там ret выкинет вас в никуда). Но тогда эпилог не нужен (из ExitProcess всё равно не будет возврата).
            ExpandedWrap disabled
              include c:\masm32\include64\masm64rt.inc
               
              NOSTACKFRAME
               
              .code
               
              my_test proc
              LOCAL p : QWORD
               
                  push rbp
                  mov rbp, rsp
                  sub rsp, 32+8+8 ; эти 3 инструкции можно заменить на один enter 48,0
               
                  mov rcx,1234567890ABCDEFh
                  mov p,rcx   ; test
               
                  call GetProcessHeap
                  mov rcx, rax
                  mov edx, HEAP_ZERO_MEMORY
                  mov r8d, 24
                  call HeapAlloc
               
                  mov rcx,p   ; test
               
                  leave
                  ret
              my_test endp
               
              main proc
                  push rbp
                  mov rbp, rsp
                  sub rsp, 50h    ; эти 3 инструкции тоже можно заменить на enter 50h,0
               
                  call my_test
                  leave  ; хотя, здесь это можно убрать, всё равно вызываем ExitProcess
                  invoke ExitProcess,0
              main endp
               
              end
              Jin X, к переменной обращения вообще нет. На самом деле значение этой переменной изменяется уже после вызова GetProcessHeap. Но это всё действительно из-за того что Delphi делает по странному кадр фрейма, а именно размещение локальных переменных.
              0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
              0 пользователей:


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