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

#assembly #x87 #cheat-engine

#сборка #x87 #чит-движок

Вопрос:

Я считаю, что правильный способ сделать это следующий:

 const1:     dq  1.2345
...
     fld    const1
  

Тем не менее, я использую Cheat Engine для обратного проектирования игры (чтобы я мог лучше ее понять). И это показывает следующую ошибку:

не удается загрузить чит-движок, показывающий постоянное значение

Может кто-нибудь, пожалуйста, сказать мне, что здесь не так? В идеале я хотел бы, чтобы вторая команда была:

 fstp dword [esi  3C]
  

Но прежде чем я это сделаю, мне нужно загрузить значение 93.5 в регистр st (0). Как я могу этого добиться?

Комментарии:

1. Обратитесь к документации cheat engine о том, как инициализировать константы с плавающей запятой. Если все остальное не удается, и вы знаете, как инициализировать байты данных, преобразуйте ваше значение. На самом деле это может быть самым простым решением, вы можете заменить все это просто mov dword [esi 3C], 0; mov dword [esi 40], 0x40576000 . Нет константы в памяти, fld или fstp не требуется. Непонятно, почему у вас их два fstp , поскольку первое извлекает значение из стека.

2. @Jester Извините за двусмысленность и спасибо, что подняли этот вопрос! Мне нравится ваша идея использовать для этого простой оператор mov. Первая метка памяти «newmem» — это то, с чего должно начаться выполнение нашего кода. Это включает в себя 3 новые строки, которые я написал (val, fld и fstp). На этом этапе наша работоспособность сохраняется в регистре st (0), а затем выполняются эти 3 инструкции (ну, 1 метка 2 инструкции). Как только мой код будет выполнен, я хочу иметь большое значение в st (0) и адрес памяти. Все, что после этого (метка «code»), является уже существующим кодом (исходный код игры).

3. Если вам нужно одно и то же значение в st0 и в памяти, вы можете перезагрузить его с помощью fld dword [esi 3C] .

4. Помимо синтаксической ошибки, у вас есть данные и код рядом друг с другом. Если выполнение перейдет на newmem: , байты double 93.5 будут декодированы как инструкции.

5. @Jester Это великолепно! Не могли бы вы добавить оба ваших пункта в качестве ответа, чтобы я мог выбрать его и завершить этот вопрос?

Ответ №1:

Существует ряд ошибок, связанных с синтаксисом, вызывающих вашу проблему.

«эта инструкция не может быть скомпилирована» Вы помещаете данные в раздел кода. Определите свою переменную вне блока newmem и внутри отдельного блока памяти. Вы пытаетесь определить блок памяти с помощью «val:», но вы не выделили эту память. Вы также не можете ссылаться на него без регистрации символа.

Для определения обычного значения с плавающей запятой вы используете 4-байтовую переменную, а не 8-байтовую переменную, поэтому вы используете «dd», а не «dq», во-вторых, вам нужно «преобразовать» его в значение с плавающей запятой.

Ваша инструкция, по которой вы хотите поместить значение с плавающей запятой в стек FPU, записана следующим образом: fld dword ptr [val]

Создайте шаблон внедрения, как вы делали ранее, а затем вставьте этот код вверху и продолжайте то, что вы делали, в нем есть все, что я отметил в ответе, и я протестировал его работу:

 alloc(newmem,2048)
label(returnhere)
label(originalcode)
label(exit)

alloc(val,8)

val:
dd (float)93.5

registersymbol(val)

newmem:
fld dword ptr [val]
  

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

Комментарии:

1. @PeterCordes этот небольшой фрагмент в верхней части вопроса является случайной копией и вставкой из какого-то руководства. Опубликованный мной код представляет собой синтаксис скриптового движка. Cheat Engine не принимает «fldl», только что попробовал

2. @PeterCordes Я считаю, что это была опечатка. В реальном коде нет fldl, как показано на скриншоте. Извините за путаницу. Я обновил его сейчас.

3. @Mugen: Вот почему вы всегда копируете / вставляете код в SO для вопросов по отладке:/ В вашем примере по-прежнему отсутствуют квадратные скобки или спецификатор размера. Это сработало бы в некоторых ассемблерах, таких как MASM, но было бы недопустимым в других, таких как NASM или GAS, где объявление не подразумевает размер для других инструкций, использующих его. Опять же, проверьте, близок ли ваш пример за пределами скриншота к допустимому синтаксису Cheat Engine.

4. @PeterCordes Я понимаю, что вы пытаетесь помочь, но я чувствую, что вы уже высказали свою точку зрения по поводу «копирования-вставки». Да, я всегда выполняю копирование / вставку. Я люблю копировать / вставлять в большинстве случаев. Однако нет КОДА для копирования / вставки. Если бы это было так, я бы просто скопировал / вставил решение. Я не знаю синтаксис сборки с плавающей запятой должным образом, и я все еще изучаю его. Весь смысл примера состоял в том, чтобы дать представление о том, чего я пытаюсь достичь. Если вы заметили, там также есть многоточие. Код не будет выполняться до тех пор, пока многоточие тоже присутствует, не так ли? Оно есть…

5. … чтобы привлечь внимание к области, где мне нужна помощь. И я нахожу ваше поведение близким к издевательствам. Пока я пытаюсь разобраться в основах языка ассемблера с плавающей запятой, вы ожидаете, что я знаю о MASM, NASM и GAS. Я здесь, чтобы учиться, но мне, конечно, не нравится, каким образом вы постоянно обвиняете меня в незнании той самой области, в которой я поднял вопрос.