Я пытаюсь запустить двоичную программу, которая использует инструкцию CMPXCHG16B
в одном месте, к сожалению, мой Athlon 64 X2 3800+ не поддерживает ее. Это здорово, потому что я рассматриваю это как проблему программирования. Кажется, что инструкция не сложна для реализации с пещерным прыжком, так что то, что я сделал, но что-то не сработало, программа просто застыла в цикле. Может быть, кто-нибудь скажет мне, если я внедрил свой CMPXCHG16B
неправильно?
Во-первых, фактический кусок машинного кода, который я пытаюсь подражать, заключается в следующем:
f0 49 0f c7 08 lock cmpxchg16b OWORD PTR [r8]
Отрывок из руководства Intel, описывающий CMPXCHG16B
:
Сравните RDX: RAX с m128. Если он равен, установите ZF и загрузите RCX: RBX в m128. Вновь очистите ZF и загрузите m128 в RDX: RAX.
Сначала я заменяю все 5 байтов инструкции прыжком на кодовую пещеру с моей процедурой эмуляции, к счастью, прыжок занимает ровно 5 байтов! Скачок фактически является инструкцией call
e8
, но может быть jmp
e9
, оба работают.
e8 96 fb ff ff call 0xfffffb96(-649)
Это относительный прыжок с 32-битным смещенным смещенным, закодированным в двух дополнениях, смещение указывает на кодовую пещеру относительно адреса следующей команды.
Затем код эмуляции, с которым я перехожу,:
PUSH R10
PUSH R11
MOV r10, QWORD PTR [r8]
MOV r11, QWORD PTR [r8+8]
TEST R10, RAX
JNE ELSE
TEST R11, RDX
JNE ELSE
MOV QWORD PTR [r8], RBX
MOV QWORD PTR [r8+8], RCX
JMP END
ELSE:
MOV RAX, r10
MOV RDX, r11
END:
POP R11
POP R10
RET
Лично я доволен этим, и я думаю, что он соответствует функциональной спецификации, приведенной в руководстве. Он восстанавливает стек и два регистра r10
и r11
в исходный порядок, а затем возобновляет выполнение. Увы, это не сработает! Это код работает, но программа действует так, как будто она ждет наконечника и сжигания электричества. Что указывает на то, что моя эмуляция не была идеальной, и я случайно побил ее. Вы видите что-то не так с этим?
Я замечаю, что это атомный вариант этого, владеющий префиксом lock
. Я надеюсь, что это что-то еще, кроме того, что я сделал не так. Или есть способ эмулировать атомарность?