BP вместо EBP в команде LEA

Тема в разделе "WASM.ASSEMBLER", создана пользователем NCRangeR, 22 ноя 2004.

  1. NCRangeR

    NCRangeR New Member

    Публикаций:
    0
    Регистрация:
    21 окт 2004
    Сообщения:
    6
    Адрес:
    Russia
    Проблема в следующем:

    Изначально в программе имелась инструкция вида
    Код (Text):
    1. lea eax, [ebp + offset data_end]




    Прочитав про то, как можно сэкономить пару лишних байт на дельта-смещении (не вычитая предварительно из ebp "offset delta"), я написал следующее:
    Код (Text):
    1. lea eax, [ebp + offset data_end - offset delta]




    После этого возникла такая проблема: компилятор (masm) во втором случае вместо
    Код (Text):
    1. lea eax, [ebp+159h]


    генерирует
    Код (Text):
    1. lea eax, [[b]bp[/b]+159h]




    Так происходит во всех аналогичных инструкциях (даже то, что должно в конце выглядеть как lea eax, [ebp+10] превращает в lea eax, [bp+10]).



    Т.е., lea eax, [ebp + offset a] ; lea eax, [ebp + 10] компилируется правильно, а lea eax, [ebp + offset a - offset delta] - нет.



    Проверялось при помощи SoftIce (также в поддержку этого факта говорит Application Error при попытке сделать jmp eax :))



    Пробовал писать lea eax, [dword ptr ebp + offset data_end - delta], но не помогло.



    Компилятор - masm 6.15

    Линкер - ms incremental linker 5.12.8087
     
  2. zzzyab

    zzzyab New Member

    Публикаций:
    0
    Регистрация:
    13 май 2004
    Сообщения:
    115
    У меня тоже 6.15 масм, линкер думаю на код не влияет.



    На lea eax, [ebp + offset data_end - offset delta]

    масм выдает ошибку два оffseta нельзя так что это не правильный синтаксис.



    А lea eax, [ebp + offset data_end - число] работает нормально. Где ты прочитал про "дельта смещение" может это маразм какойто. Короче убери все слова "offset" и ставь числа. Влом числа запоминать тогда обозначь их через '=' в слова и через 'equ' если это константы

    ер. data_end = 10, delta equ 345 ......
     
  3. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    NCRangeR

    Покажи листинг.

    У меня (6.14, 6.15, 7.00.xx) генерируется
    Код (Text):
    1. 8D 85 00000159    lea eax,[ebp + offset data_end - offset delta]
    что соответствует описанию команды, правда появляется сообщение об ошибке, как указал zzzyab.



    можно сэкономить пару лишних байт

    Как? Afaik экономия только если (offset data_end - offset delta) < 256
     
  4. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    q_q >




    Случай, о котором ты говоришь не < 256, а -128 <= offset <= 127,

    здесь же такой вариант:
    Код (Text):
    1. 67:8D86 5901    lea     eax, [bp+159]
    2.  
    3. и
    4.  
    5. 8D85 59010000   lea     eax, [ebp+159]






    NCRangeR >




    После такой LEA старшие 2 байта EAX = 0, так что ты пытаешся ваполнить код в 0й странице памяти, если бы ты лействительно отлаживал прогу в сайсе, то увидел бы это.





    >




    Покажи код с директивами .model и т.п.
     
  5. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    S_T_A_S_

    Точно -128/+127.

    Afaik, применительно к 32-ух разрядному режиму смещение может быть либо 1 байт, либо 4 байта.
     
  6. captain cobalt

    captain cobalt New Member

    Публикаций:
    0
    Регистрация:
    21 дек 2003
    Сообщения:
    222
    Адрес:
    /ru/perm
    NCRangeR

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



    А где прочитав об этом?



    > (не вычитая предварительно из ebp "offset delta"), я написал следующее:

    > lea eax, [ebp + offset data_end - offset delta]



    Да, это правильная идея.

    Более того, выбрав delta == data_end можно было бы сэкономить ещё один байт (но не при базовой адресации от ebp, как здесь)



    q_q> Afaik, применительно к 32-ух разрядному режиму

    q_q> смещение может быть либо 1 байт, либо 4 байта.



    Да, это верно.

    Так что "пара лишних байт" == 3 байта. ;)



    P.S. Я, конечно, не знаю, что такое masm 6.15, но что если некоторые (или все) операторы заключить в скобки? Так:
    Код (Text):
    1. lea eax, [ebp + ((offset data_end) - (offset delta))]
     
  7. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    captain cobalt

    что если некоторые (или все) операторы заключить в скобки

    Оказывалось достаточно скобок вокруг разницы.



    ml 6.15 для (offset data_end - offset delta) < 127 создал
    Код (Text):
    1. 8D 45 ??          lea eax, [ebp + (offset data_end - offset delta)]
    а для 159h по прежнему
    Код (Text):
    1. 8D 85 ????????    lea eax, [ebp + (offset data_end - offset delta)]




    не знаю, что такое masm 6.15

    Это ml.exe из Visual C++ 6.0 Processor Pack.
     
  8. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    q_q >




    LEA хитрая команда.

    2й операнд (то, что стоИт после запятой) - это адрес, соответственно, к нему можно применить префикс смены разрядности адреса (67h).

    При этом смещение будет 16ти битным (кодироваться 2мя байтами).

    Однако, добавляется байт префикса, так что экономия всего байт.

    Ещё нужно учитывать, что поле REG байта ModR/M имеет различное значение в различных режимах адресации, так что при добавлении префикса, это поле нужно корректировать.



    Вот влияние префиксов на LEA в 32х разрядном режиме:
    Код (Text):
    1.  
    2.       8D85 59010000 lea     eax, [ebp+159]
    3.  
    4. 67    8D8[b]6[/b] 5901     lea     eax, [bp+159]
    5.  
    6. 66    8D85 59010000 lea     ax, [ebp+159]
    7.  
    8. 66 67 8D8[b]6[/b] 5901     lea     ax, [bp+159]
    9.  


    IMHO NCRangeR компилирует прогу в "каком-нибудь не 32х битном режиме", поэтому и появился BP.
     
  9. NCRangeR

    NCRangeR New Member

    Публикаций:
    0
    Регистрация:
    21 окт 2004
    Сообщения:
    6
    Адрес:
    Russia
    По поводу экономии - http://www.wasm.ru/article.php?article=1010001

    Вкратце, обычно пишут
    Код (Text):
    1. call gdelta
    2. gdelta: pop ebp
    3. sub ebp, offset gdelta


    и lea eax, [ebp + variable] ,

    а в статье предлагается offset delta вычитать не сразу, а при каждом обращении. Действительно, экономия получается при <128 байтах, но даже для такого случая получается некорректный выход компилятора.



    Ошибок компиляции у меня masm не выдавал, убрать offset-ы или поставить 67h-ей не помогло.



    Помогло же поставить скобки (как для <128, так и для всех остальных):
    Код (Text):
    1. lea eax, [ebp + (data_end - delta)]




    Всем спасибо за ответы!



    На всякий случай прилагаю исходник (пофиксенный), но, кажется, режим там самый что ни на есть 32-битный, и т.д., и т.п.



    Для меня (пока) так и осталось непонятным - баг это или фича... ;)

    [​IMG] _1193762143__v.Asm