Сохранение и восcтановление данных командами ассемблера - fxsave и fxrstor

Тема в разделе "WASM.BEGINNERS", создана пользователем assch, 1 янв 2025.

  1. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    208
    если я выделяю память в сегменте данных
    инициализирую например регистр (xmm3) значением - 123
    при помощи команды (fxsave) сохраняю данные
    инициализирую регистр (xmm3) уже значением - 456
    потом восстанавливаю данные командой (fxrstor)
    Код (ASM):
    1.  
    2. .data?
    3. wert db 1024 dup (?)
    4. .code
    5. mov eax,123
    6. movd xmm3,eax
    7. fxsave wert
    8. mov eax,456
    9. movd xmm3,eax
    10. fxrstor wert
    11.  
    всё отлично восcтанавливается
    в регистре (xmm3) опять значение - 123
    но если я вместо сегмента данных выделяю динамическую память из кучи
    Код (ASM):
    1.  
    2. .data?
    3. buf dd ?
    4. .code
    5. invoke VirtualAlloc,0,1024,MEM_COMMIT or MEM_RESERVE,PAGE_READWRITE
    6. mov buf,eax
    7. mov eax,123
    8. movd xmm3,eax
    9. fxsave buf
    10. mov eax,456
    11. movd xmm3,eax
    12. fxrstor buf
    13.  
    то в этом случае регистр (xmm3) не восcтанавливается
    и в нём значение даже не (456) а просто ноль
    почему в сегменте данных можно сохранить данные
    а в выделенной динамической памяти из кучи это не получается
     
  2. MaKsIm

    MaKsIm Active Member

    Публикаций:
    0
    Регистрация:
    11 фев 2008
    Сообщения:
    120
    Память не правильно выравнена. Попробуйте выделить из кучи больший кусок память и сохраните в нем значения по выравненному на 512 адресу. Хотя, возможно, достаточно и выравнивания на 64, но лезть уточнять не хочу. А в памяти осталось что-то про 512 с выравниванием для блока сохранения fxsave

    Хотя, судя по использованию VirtualAlloc, стоит проверить память на успешность её выделения. т.к. вы её выделяете не из кучи, а через пользовательский интерфейс страничного механизма работы с секциями памяти.
     
  3. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    208
    вроде бы нашёл подводный камень
    в принципи выравнивание достаточно на - 16
    первый код где сохранение в сегменте данных
    по сути сработал чисто случайно видимо лексема уже была выровнена
    и чтобы исключить случайность лучше явно выровнить память
    Код (ASM):
    1.  
    2. .data?
    3. align 16
    4. wert db 512 dup (?)
    5. .code
    6.  
    во втором коде оказывается тоже у лексемы в которой пропишется адрес памяти
    который не сомненно выровнен даже по размеру странице
    но вот оказывается этого мало и нужно было чтобы сама лексема
    инициализированная адресом памяти тоже бала бы выровнена по границе - 16
    Код (ASM):
    1.  
    2. .data?
    3. align 16
    4. buf dd ?
    5. .code
    6.  
    вроде бы заработало
    всем спасибо
     
  4. Ahimov

    Ahimov Member

    Публикаций:
    0
    Регистрация:
    14 окт 2024
    Сообщения:
    64
    В IA нет дереференсов ссылок, тоесть нет обращений в память по указателю на указатель. В Buf указатель(ссылка) на буфер, в инструкции fxsave [[buf]] две адресные предвыборки, а такого быть не может :preved:
     
  5. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    208
    оказывается даже если лексеме занести адрес динамической памяти
    и эту лексему поставить параметром - fxsave
    то сохранение не будет в динамической памяти
    а будет по адресу этой лексемы в сегменте данных
    а чтобы сохранение было в динамической памяти,то параметр этим командам
    нужно передовать наверное только косвенным указателем через регистр
    Код (ASM):
    1.  
    2. .data?
    3. buf dd ?
    4. .code
    5. invoke VirtualAlloc,0,512,MEM_COMMIT or MEM_RESERVE,PAGE_READWRITE
    6. mov buf,eax
    7. mov eax,123
    8. movd xmm3,eax
    9. mov eax,buf
    10. fxrstor [eax]
    11. ...
    12. mov eax,456
    13. movd xmm3,eax
    14. ...
    15. mov eax,buf
    16. fxrstor [eax]
    17.  
     
  6. Ahimov

    Ahimov Member

    Публикаций:
    0
    Регистрация:
    14 окт 2024
    Сообщения:
    64
    В параметрах инструкции линейный адрес: он вычисляется, проверяются права доступа, адресная трансляция и тд, это все предвыборка(prefetch). Затем уже выполняется выборка из памяти. Предвыборка может быть лишь одна для одного адреса.

    mov eax,buf тоесть mov r,[m] выборка указателя, затем вторая по этому указателю в fsave.

    mov eax,buf в ней адресация не явная, может быть это загрузка смещения или выборка по смещению, отсюда у тс путаница. Следует посмотреть режимы адресации IA sdm.
     
  7. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    208
    исправил ( в прошлый пост два раза прописал команду - fxrstor)
    Код (ASM):
    1.  
    2. .data?
    3. buf dd ?
    4. .code
    5. invoke VirtualAlloc,0,512,MEM_COMMIT or MEM_RESERVE,PAGE_READWRITE
    6. mov buf,eax
    7. mov eax,123
    8. movd xmm3,eax
    9. mov eax,buf
    10. fxsave [eax]
    11. ...
    12. mov eax,456
    13. movd xmm3,eax
    14. ...
    15. mov eax,buf
    16. fxrstor [eax]
    17.  
     
  8. assch

    assch Member

    Публикаций:
    0
    Регистрация:
    17 мар 2011
    Сообщения:
    208
    Небольшое уточнение -- если применять динамическую память, то именно выделенную функцией - VirtualAlloc так как она выделяет память по границе страницы, то есть точно выровненную по 16-байтной границе, а если например выделить память функцией - HeapAlloc, то гарантии нет что память будет выровнена по 16-байтной границе, а например по 8-байтной границе можно конечно адрес разделить на 16 и остаток прибавить к адресу, но это кому как нравиться
     
  9. Indy_

    Indy_ Well-Known Member

    Публикаций:
    4
    Регистрация:
    29 апр 2011
    Сообщения:
    4.764
    Стало быть нужно эзин0с почитать:

    eof.rrlf