jmp vs push ret

Тема в разделе "WASM.BEGINNERS", создана пользователем Codegrammer, 21 май 2010.

  1. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    dermatolog
    Про то, что надо сначала прочитать, что пишут, прежде чем переходить к унизительным рекомендациям.
    С учётом своей поправки, K10 ничего неверного не написал.
     
  2. dermatolog

    dermatolog Member

    Публикаций:
    0
    Регистрация:
    3 фев 2005
    Сообщения:
    406
    Адрес:
    Екатеринбург
    l_inc
    Если бы человек с самого начала называл вещи своими именами, то и унизительных рекомендаций тоже не последовало. Пойди разбери что они понимают под адресом перехода, если речь идет про сплайсинг. Если под "адресом перехода" подразумевается адрес возврата в вызывающий код, то видимо придется отправлять еще дальше (что такое стек и CALL).
     
  3. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    dermatolog
    С учётом своей поправки, которую Вы, кстати, и процитириовали, и в которой своеобразное понятие "адреса перехода" уже не фигурирует, а как раз поясняется.
    Хм... Не согласен. Но Вам виднее.
     
  4. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    На мой наивный взгляд

    JMP XXX
    это
    ADD EIP,XXX

    PUSH
    RET
    это
    MOV EIP,[ESP]
    ADD ESP,4

    Разве не так?
     
  5. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    всё не так )
    примерный псевдокод в манах интел можно глянуть.
     
  6. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    dermatolog
    >Для х32 - согласен, но я в целом говорил про универсальных подход в том числе и для х64.
    Нет, в том месте ты не говорил про x64 – ты противопоставлял jmp и push\ret. Если бы акцент в тот момент был на универсальности подхода, то ты не стал бы после своей фразы про ограниченность jmp добавлять "в случае с PUSH аргумент принимает любое значение от 0 до 4Гиг".

    medstrax1
    Clerk
    >>lock cmpxchg8b
    >Код изменять следует атомарно.
    Ok. А зачем нужен lock-префикс здесь? Есть неконтролируемые потоки, бегущие параллельно с нами, собирающиеся точно таким же образом просплайсить ту же функцию?
     
  7. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Sol_Ksacap
    Затем что например первый поток патчит код, в это время другой поток его вызывает. Если делать это побайтным копирование допустим, то первый байт изменился при записи, остальный нет. Поток исполнит не до конца изменённую инструкцию, что приведёт к краху. Если изменять атомарно, то изза захвата шины другой процессор будет ждать пока запись окончится.
     
  8. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Sol_Ksacap
    Хотя префикс не обязательный. Видимо инструкция и без него атомарно пишет, нужно в манах посмотреть. Потестил так:
    Первый поток:
    Код (Text):
    1. @@:
    2.     xor eax,eax
    3.     xor ecx,ecx
    4. Ip::
    5.     mov eax,12345678H
    6.     cmp eax,12345678H
    7.     je @b
    8.     cmp ecx,87654321H
    9.     je @b
    10.     int 3
    Изменяем инструкцию по адресу [Ip] на mov eax,12345678H и mov ecx,87654321H. Если после исполнения её значения регистров будут отличными от этих значит ошибка. При записи без cmpxchg8b возникает ошибка. При записи посредством этой инструкции без префикса Lock ошибка не возникает, тоесть изменяется атомарно:
    Второй поток:
    Код (Text):
    1. @@:
    2. ; -> mov eax,12345678H
    3.     xor eax,eax
    4.     xor edx,edx
    5.     cmpxchg8b qword ptr [Ip]    ; Edx:Eax
    6. ; [Mem64] == Edx:Eax    [Mem64] <- Ecx:Ebx
    7. ; [Mem64] <> Edx:Eax    Edx:Eax <- [Mem64]
    8.     mov ecx,edx
    9.     mov ebx,345678B8H   ; Eax
    10.     mov cl,12H
    11.     cmpxchg8b qword ptr [Ip]
    12. ; -> mov ecx,87654321H
    13.     xor eax,eax
    14.     xor edx,edx
    15.     cmpxchg8b qword ptr [Ip]
    16.     mov ecx,edx
    17.     mov ebx,654321B9H
    18.     mov cl,87H
    19.     cmpxchg8b qword ptr [Ip]
    20.     jmp @b
    Хотя я всегда использовал префикс Lock, думаю он не помешает, например при изменении ссылок.
     
  9. Medstrax

    Medstrax Забанен

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    673
    Согласно манов атомарность будет соблюдаться в следующих случаях
    1)Reading or writing a quadword aligned on a 64-bit boundary
    2)Unaligned 16-, 32-, and 64-bit accesses to cached memory that fit within a cache line
    Видимо в данном случае одно из условий соблюдено. Лучше все-таки не полагаться на случай и юзать lock
     
  10. Rockphorr

    Rockphorr Well-Known Member

    Публикаций:
    0
    Регистрация:
    9 июн 2004
    Сообщения:
    2.622
    Адрес:
    Russia
    Clerk
    попробуй проверить соображение medstrax1 сдвинь модифицируемую инструкцию на невыровненный(некратный) адрес
     
  11. Rockphorr

    Rockphorr Well-Known Member

    Публикаций:
    0
    Регистрация:
    9 июн 2004
    Сообщения:
    2.622
    Адрес:
    Russia
    + еще соображение запись идет двойными словами ??? - модифицируйте 5-ти байтную инструкцию
     
  12. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Rockphorr
    Адрес 0x401007.
    Это и делаем.
     
  13. Sol_Ksacap

    Sol_Ksacap Миша

    Публикаций:
    0
    Регистрация:
    6 мар 2008
    Сообщения:
    623
    Ага. Отлично. Теперь мы видим превосходство lock. Однако в манах есть такой интересный момент:
    Хотя тут же следует заметка:
    (Про более новые процессоры в том месте явно ничего не говорится, к сожалению).
     
  14. Medstrax

    Medstrax Забанен

    Публикаций:
    0
    Регистрация:
    18 июл 2006
    Сообщения:
    673
    Да, ситуация запутывается. Вообще фраза "Only instruction fetch and page table accesses can pass locked instructions" не совсем ясна. Идет ли речь о произвольном ядре/проце, либо только о том, которое выполняет lock. Исходя из "However, Intel recommends that developers who require the use of self-modifying code use a different synchronizing mechanism, described in the following sections", можно предположить, что речь идет только о текущем ядре, в противном случае вместо "self-modifying" было бы "сross-мodifying". Если же это не так, тогда
    использование lock в данном контексте излишне, на грабли можно нарваться как с ним, так и без него. Ждем leo ;)