Страницы

Поиск по вопросам

понедельник, 23 декабря 2019 г.

Опкод команды mov/xor

#ассемблер


В листинге дизассемблированного файла имею:

.text:00401296                 cmp     eax, 0 .text:00401299          
jz      short loc_4012B0


Пронзив исполняемый файл hex-редактором, лечу на адрес 696 (адрес первой команды
cmp) и там смотрю такие байты:

83 F8 00


Пытаюсь разобраться..
Топаю на http://sparksandflames.com/files/x86InstructionChart.html
Там мне подсказывают, что 


  83 - SUB Ev Ib...


Вычитание? Не сравнение? В самой программе он работает как сравнение.. Привычный
мир рушится...

Вопросы:


Почему 83 - вычитание, а не сравнение или опкод "модифицируется" каким-то спец. байтом?
Как вычислить опкод команды mov eax,eax (не 89 F8 00 случаем?). 


Как в этом случае будет влиять на ход программы байт mod r/m?
Или xor eax,eax? (не 35 F8 F8 случаем?)



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


Ответы

Ответ 1



Команда целиком состоит из трех байт: 83 F8 00 83h - это только часть опкода. Как уже заметил VladD, это может соответствовать командам ADD, OR, ADC, SBB, AND, SUB, XOR и CMP. Чтобы понять, что это за команда фактически, нужно смотреть следующий байт (F8h). Это байт MOD R/M, состоящих из 3 полей (по 2, 3, 3 бита): F8 == 11 111 000 По второму полю этого байта можно определить конкретную команду (хотя, обычно оно отвечает за один из операндов) - как раз из списка ADD, OR, ADC, SBB, AND, SUB, XOR и CMP. Первое поле показывает, что второй (на самом деле первый) операнд - это регистр (или адрес в памяти, но в данном случае это все же регистр). 000 - это, собственно, код регистра, EAX. Третий байт является вторым операндом команды - 0. Больше по этой теме можно почитать, например, здесь: Крис Касперски - Дизассемблирование в уме. А еще лучше - читать руководства от Intel в оригинале. Используемый вами справочник очень не полный. Как вычислить опкод команды mov eax,eax? Скомпилировать и посмотреть, это наиболее надежный способ, или смотреть в руководстве от Intel. Или xor eax,eax? (не 35 F8 F8 случаем?) Скорее 31 C0. Второй байт - байт mod r/m, там просто указывается, что производится операция производится между регистром и регистром, и коды самих регистров: 11 000 000 (000 в обоих случаях - обозначение регистра eax). А первый байт - не 35h, а 31h, т.к. операция не между регистром/памятью и значением, а между регистром и регистром/памятью.

Ответ 2



Сравнение содержимого регистра с числов равноценно вычитанию из регистра этого числа. Т.е. по сути SUB eax 0 и CMP eax 0 равноценны по результату. При совпаднеии числе в результате получается ноль и срабатывает переход JZ В данном случае я думаю, что программист реализовавывл сравнение вычитанием, а CMP поставил слишком "умный" дизассемблер.

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

Отправить комментарий