turbo pascal и дизассемблер

Тема в разделе "WASM.RESEARCH", создана пользователем _jungle_, 14 ноя 2005.

  1. _jungle_

    _jungle_ New Member

    Публикаций:
    0
    Регистрация:
    7 окт 2005
    Сообщения:
    21
    Адрес:
    Russia
    проблема такая. Мне дали программу на паскале. Я ее дизассемблировал.Вижу там вызов getmem в такой форме:


    Код (Text):
    1.  
    2. seg000:01C7                 push    ds
    3. seg000:01C8                 push    di
    4. seg000:01C9                 mov     ax, 8 ;
    5. seg000:01CC                 push    ax
    6. seg000:01CD                 call    @GetMem$qm7Pointer4Word ; GetMem(Pointer &,Word)
    7.  




    где ds:di - как я понял это адрес указателя.Туда помещается адрес выделенной памяти.

    То есть тут передается адрес указателя и туда записывается значение адреса выделенной памяти.Сама функция getmem ничего не возвращает.

    Сделал похожую программу на паскале:


    Код (Text):
    1.  
    2. var p:pointer;
    3. begin
    4. GetMem(p,sizeof(integer)*4);
    5. freemem(p,sizeof(integer)*4);
    6. end.
    7.  




    и ее тоже дизассемблировал:
    Код (Text):
    1.  
    2.  
    3. seg000:000F                 mov     ax, 8           ; DATA XREF: Halt(Word)+1C\19r
    4. seg000:0012                 push    ax
    5. seg000:0013                 call    @GetMem$q4Word  ; DATA XREF: Halt(Word):loc_195\19r
    6. seg000:0013                                         ; GetMem(var p: Pointer{DX:AX}; size: Word)
    7. seg000:0018                 mov     word_890, ax
    8. seg000:001B                 mov     word_892, dx
    9.  


    А тут получается, что передается только размер выделяемой памяти,а адрес выделяемой памяти возвращается через dx:ax и уже потом записывается в указатель.

    Вообщем-то и названия функции дизассемблер определил как разные:

    call @GetMem$qm7Pointer4Word ; GetMem(Pointer &,Word) и

    call @GetMem$q4Word ; GetMem(var p: Pointer{DX:AX}; size: Word)

    Вот не понимаю, как сделать так, чтобы было так же как в исходной программе.Думал разные версии компиляторов(про ту хз, а мой - 7.0).Программа file analyser сказала, что версия компилятора 6.0 или 7.0.На всякий случай скачал 6.0 - но там оказалось то же самое.
     
  2. DenKor

    DenKor New Member

    Публикаций:
    0
    Регистрация:
    3 авг 2004
    Сообщения:
    32
    Могут быть разные директивы компиляции и соглашения об типах аргументах для процедур.



    А зачем тебе делать похоже ?
     
  3. _jungle_

    _jungle_ New Member

    Публикаций:
    0
    Регистрация:
    7 окт 2005
    Сообщения:
    21
    Адрес:
    Russia
    Ну впринципе действительно это не то чтобы надо.

    Просто я хочу код восстановить, думал, может я что-то вообще в корне неправильно понимаю...

    Ну и просто когда обратил внимание на это, стало интересно, почему же так...

    Действительно скорее всего это настройки компилятора.
     
  4. CyberManiac

    CyberManiac New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2003
    Сообщения:
    2.473
    Адрес:
    Russia
    Может, это был другой GetMem? Никто ведь не запрещает сочинить функцию с таким же именем в своем модуле. Насчет соглашений маловероятно, т.к. GetMem - стандартная функция системной библиотеки, число и порядок аргументов - задокументированы.
     
  5. _jungle_

    _jungle_ New Member

    Публикаций:
    0
    Регистрация:
    7 окт 2005
    Сообщения:
    21
    Адрес:
    Russia
    да не, дизассмеблер не обозвал бы ее тогда getmem. просто какая-нить call loc_XXX. А тут он ее выделил.

    Насчет кол-ва элементов - GetMem(var p: Pointer{DX:AX}; size: Word)(это из 2-го случая) - подразумевает 2 эл-та(само описание функции).
     
  6. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    В борландовских паскалях и дельфях множество функций system реализовано на уровне "compiler magic", т.е. на самом деле реализация и вызов функции может выглядеть вовсе не так, как она объявлена в документации. TP под рукой у меня нет, но в дельфях вообще нет реализации процедуры GetMem, а есть функции _GetMem и SysGetMem = function(Size:integer):pointer. Поэтому вместо вызова GetMem компилер подставляет вызов _GetMem и затем копирует результат EAX или DX:AX в переменную.

    А первый вариант скорее всего соответствует ReallocMem, хотя в дельфях она тоже реализована через функцию function _ReallocMem(P:pointer;Size:integer):pointer;
     
  7. spanther

    spanther New Member

    Публикаций:
    0
    Регистрация:
    18 дек 2005
    Сообщения:
    7
    В паскале, вообще, были NEW()/DISPOSE(). Так что не зацикливайся на GETMEM()/FREEMEM().
     
  8. leo

    leo Active Member

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

    В документации она объявлена как procedure New(var P:pointer), а на самом деле реализуется через функцию function _New(size:integer;typeinfo:pointer):pointer. Вроде бы похоже на вызов, приведенный _jungle_, но загвоздка в том, что в TP используется вызов pascal (или register), а при pascal параметры пушатся в стек слева направо, т.е. первым должен пушиься size, а потом указатель на typeinfo