Перейти к содержанию

Как поместить значение в структуру, имея указатель на другую структуру с ним?


Рекомендуемые сообщения

Есть структура, Выглядит так:

Скрытый текст

08 - общее количество патронов

0С - патроны в обойме

 

kiss_22kb.1467725209.png

 

Перед этими значениями есть указатель:

Скрытый текст

Указатель адресует память со структурой, в которой лежат максимумы значений.

08 - общее количество патронов

14 - количество патронов в обойме

 

kiss_22kb.1467725284.png

Собственно, как это сделать?

Ссылка на комментарий
Поделиться на другие сайты

Скрытый текст

{ Game   : TimeShift.Exe
  Version: 
  Date   : 2016-07-05
  Author : SergBrNord
}

[ENABLE]

aobscanmodule(AMMO,TimeShift.Exe,F3 0F 10 40 08 0F 2F 05 * * * * 76 04 33 FF) // should be unique
alloc(newmem,$1000)

label(code)
label(return)

newmem:


code:
  movss xmm0,[eax+08]
  jmp return

AMMO:
  jmp newmem
return:
registersymbol(AMMO)

[DISABLE]

AMMO:
  db F3 0F 10 40 08

unregistersymbol(AMMO)
dealloc(newmem)

 

Цитата

Как поместить значение в структуру, имея указатель на другую структуру с ним?

 

Изменено пользователем SergBrNord
Ссылка на комментарий
Поделиться на другие сайты

4 минуты назад, SergBrNord сказал:

Как поместить значение в структуру, имея указатель на другую структуру с ним?

Не очень понятно. Но скорее всего ты хочешь, чтобы всегда были максимальное кол-во патронов в рожке и общее.

Выкладывайте АА-скрипт с логами внизу, который делает СЕ. Иногда нужно посмотреть код, около твоей инструкции. Ну например сейчас мне нужно было бы посмотреть свободный регистр, чтобы не использовать стек.  

Пример скрипта (с комментариями):

Скрытый текст

{ Game   : TimeShift.Exe
  Version:
  Date   : 2016-07-05
  Author : SergBrNord
}

[ENABLE]
aobscanmodule(AMMO,TimeShift.Exe,F3 0F 10 40 08 0F 2F 05 * * * * 76 04 33 FF) // should be unique
alloc(newmem,$1000)
label(code)
label(return)
registersymbol(AMMO)

newmem:
  push ebx          // сохраняем регистр перед использованием
  mov ebx,[eax+04]  // загружаем указатель в регистр ebx
  push [ebx+08]     // выгружаем max кол-во патронов в стек, сдвигая его
  pop [eax+08]      // загружаем max кол-во патронов, одновременно
                    // востанавливая стек
  push [ebx+14]     // выгружаем max кол-во патронов в рожке в стек, сдвигая его
  pop [eax+0C]      // загружаем max кол-во патронов в рожке, одновременно
                    // востанавливая стек
  pop ebx           // восстанавливаем регистр после использования

code:
  movss xmm0,[eax+08]
  jmp return

AMMO:
  jmp newmem
return:

[DISABLE]
AMMO:
  db F3 0F 10 40 08

unregistersymbol(AMMO)
dealloc(newmem)

 

 

 

  • Плюс 1
Ссылка на комментарий
Поделиться на другие сайты

А нету там свободных регистров; вообще =)

 

И как я про то, что выгрузить можно, не подумал...

Изменено пользователем SergBrNord
Ссылка на комментарий
Поделиться на другие сайты

Только что, SergBrNord сказал:

А нету там свободных регистров; вообще =)

Это не важно, просто выкладывайте с логами - это помогает тому, кто пишет скрипт без игры.

Думаю, что Дарк Байт именно для таких случаев и сделал это. 

Ссылка на комментарий
Поделиться на другие сайты

Garik, извиняюсь за тупой вопрос, но почему в данном куске кода:

Spoiler

  push [ebx+08]     // выгружаем max кол-во патронов в стек, сдвигая его
  pop [eax+08]      // загружаем max кол-во патронов, одновременно
                    // востанавливая стек
  push [ebx+14]     // выгружаем max кол-во патронов в рожке в стек, сдвигая его
  pop [eax+0C]      // загружаем max кол-во патронов в рожке, одновременно
                    // востанавливая стек

 

ты не использовал регистр? Ведь не важно, использовался он или нет, мы в любом случае сохраняем его значение и восстанавливаем

 

Например так:

Spoiler

  push ebx          // сохраняем регистры перед использованием
  push ecx

  mov ebx,[eax+04]  // загружаем указатель в регистр ebx

  mov ecx,[ebx+08]
  mov [eax+08],ecx

  mov ecx,[ebx+14]
  mov [eax+0C],ecx

  pop ecx
  pop ebx           // восстанавливаем регистры после использования

 

 

Просто интересуюсь )

Изменено пользователем holy
Ссылка на комментарий
Поделиться на другие сайты

25 минуты назад, holy сказал:

ты не использовал регистр?

Потому что для передачи данных (кол-во патронов) в данном случае я использую не регистр, а стек и непосредственно память, т.е. push - загрузили в стек, pop - выгрузили из стека.

а эту строчку:

3 часа назад, Garik66 сказал:

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

я написал, потому, что, если бы был свободный регистр, то скрипт бы был ещё короче. 

Ну например, если бы ebx был свободен (т.е. дальше по коду перезаписывался), то скрипт был бы такой:

Скрытый текст

newmem:
  mov ebx,[eax+04]  // загружаем указатель в регистр ebx
  push [ebx+08]     // выгружаем max кол-во патронов в стек, сдвигая его
  pop [eax+08]      // загружаем max кол-во патронов, одновременно
                    // востанавливая стек
  push [ebx+14]     // выгружаем max кол-во патронов в рожке в стек, сдвигая его
  pop [eax+0C]      // загружаем max кол-во патронов в рожке, одновременно
                    // востанавливая стек

code:

 

 

Ссылка на комментарий
Поделиться на другие сайты

1 minute ago, Garik66 said:

Потому что для передачи данных (кол-во патронов) в данном случае я использую не регистр, а стек и непосредственно память

Ясно.

Я просто думал, что была какая-то причина, но раз это просто желание такое, тогда понял )

Ссылка на комментарий
Поделиться на другие сайты

Ещё можно вместо стека использовать регистры FPU и тогда скрипт будет выглядеть так:

Скрытый текст

{ Game   : TimeShift.Exe
  Version:
  Date   : 2016-07-05
  Author : SergBrNord
}

[ENABLE]
aobscanmodule(AMMO,TimeShift.Exe,F3 0F 10 40 08 0F 2F 05 * * * * 76 04 33 FF) // should be unique
alloc(newmem,$1000)
label(code)
label(return)
registersymbol(AMMO)

newmem:
  push ebx          // сохраняем регистр перед использованием
  mov ebx,[eax+04]  // загружаем указатель в регистр ebx
  fld [ebx+08]      // выгружаем max кол-во патронов в регистр xmm0
  fstp [eax+08]     // загружаем max кол-во патронов, одновременно сдвигая регистры FPU назад
  fld [ebx+14]      // выгружаем max кол-во патронов в рожке в регистр xmm0
  fstp [eax+0C]     // загружаем max кол-во патронов в рожке, одновременно сдвигая регистры FPU назад
  pop ebx           // восстанавливаем регистр после использования

code:
  movss xmm0,[eax+08]
  jmp return

AMMO:
  jmp newmem
return:

[DISABLE]
AMMO:
  db F3 0F 10 40 08

unregistersymbol(AMMO)
dealloc(newmem)

 

 

Ссылка на комментарий
Поделиться на другие сайты

23 минуты назад, holy сказал:

но раз это просто желание такое

Причём здесь желание :D?

Просто чем короче код, меньше кушает памяти и загружает проц, тем лучше.

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

Потому лучше изначально учиться писать правильно.

Ссылка на комментарий
Поделиться на другие сайты

Уже оффтоп

Spoiler
13 minutes ago, Garik66 said:

Просто чем короче код, меньше кушает памяти и загружает проц, тем лучше.

Я понимаю... Я же говорю, я просто поинтересовался )

 

P.S. Про "короче код" в данном случае не подходит. Количество занимаемых байт инструкциями одинаково, вот только работа со стеком чуть медленней чем работа с регистрами процессора.


6 байт
FF73 08       PUSH DWORD PTR DS:[EBX+8]
8F40 08       POP DWORD PTR DS:[EAX+8]

6 байт
8B4B 08       MOV ECX,DWORD PTR DS:[EBX+8]
8948 08       MOV DWORD PTR DS:[EAX+8],ECX

 

Ссылка на комментарий
Поделиться на другие сайты

28 минуты назад, holy сказал:

 Количество занимаемых байт инструкциями одинаково, вот только работа со стеком чуть медленней чем работа с регистрами процессора.

Только ты забыл, что вынужден ещё две инструкции прописать:

Скрытый текст

  push ecx
  ..............
  pop ecx

 

а они также используют стек и занимают два байта.

Ссылка на комментарий
Поделиться на другие сайты

Spoiler
22 minutes ago, Garik66 said:

Только ты забыл, что вынужден ещё две инструкции прописать

Только ты забыл, что у тебя 4 операции со стеком, и они увеличиваются арифметически в зависимости от количества твоих действий.

А в моем случае, операций со стеком всегда 2, а действия с регистром можно делать сколько угодно и это все-равно будет быстрее.

 

Ссылка на комментарий
Поделиться на другие сайты

35 минуты назад, holy сказал:

и это все-равно будет быстрее.

Ну спорить не буду, mov - один такт. push (pop) - 4 такта.Тогда получается, что самый производительный и экономичный скрипт (из трёх предложенных вариантов) из этого сообщения.

Ссылка на комментарий
Поделиться на другие сайты

×
×
  • Создать...

Важная информация

Находясь на нашем сайте, Вы автоматически соглашаетесь соблюдать наши Условия использования.