2017-01-19 14 views
1

Я наткнулся на это сравнение при отладке:x86 сборка - CMP не устанавливая флаг нуля правильно

| 38 19 | CMP BYTE PTR DS:[ECX], BL 

я поставил точку останова на нее и увидел это (значения в шестнадцатеричном):

ECX = 00838430 
BYTE PTR[ECX]=[00838430]=55 
EBX = 00000055 (BL = 55) 
EFLAGS = 00000314 (CF=0 OF=0 SF=0 ZF=0 AF=1 PF=1) 

Итак, я ожидал, что после выполнения этого сравнения будет установлен флаг нуля, поскольку байт, на который указывают ECX и BL, равен. Однако то, что произошло вместо этого было то, что флаг переполнения был установлен и ZF остался значение 0. После сравнения:

EFLAGS = 00000A06 (CF=0 OF=1 SF=0 ZF=0 AF=0 PF=1) 

Почему он ведет себя, как это? Связано ли это с целыми числами с подписью/без знака? Я думал, что CMP является агностиком, т. Е. Интерпретирует результат сравнения, поскольку signed/unsigned является чем-то, что будет делать следующая инструкция перехода (например, JG vs JA). За сравнением следует JNE, который берется из-за ZF = 0 и вызывает неправильные результаты.

+2

Обычно 'CMP' ли установить флаги правильно, и значения, которые вы сделали шоу указывают ZF должен быть установлен, так что я 99% уверен, что одна из ценностей ты описывающими неверен. Я бы сначала проверил содержимое памяти, уверены ли вы, что в 'ds: [ecx]'? Как вы получили этот номер? Является ли этот 32b-режим с плоской моделью памяти (ds = не важно тогда)? – Ped7g

+4

Пожалуйста, помните, что 'CMP' * * * устанавливает флаги правильно. Вините код, а не процессор. –

+1

Ну, технически у вас может быть поврежден процессор, производящий неправильные флаги после 'CMP', но если это одноразовый провал блуждающего электрона из-за столкновения рентгеновских лучей/и т. Д. (может случиться, с количеством HW в повседневной жизни шанс состоит в том, что по крайней мере немногие в настоящее время живущие люди, по крайней мере, однажды в их жизни столкнутся с такой ситуацией ... хотя они, скорее всего, не заметят), это вызовет так много плохих результаты, которые вы никогда не получите до загрузки вашей ОС и запущенного отладчика ...Поэтому, если вы не верите 'cmp', попробуйте его еще раз, и все, ищите проблему вокруг. – Ped7g

ответ

4

Я подозревал, что в отладчике есть какая-то ошибка, поэтому я попытался с другим (OllyDbg v2) и увидел, что значения, которые я опубликовал, действительно были правильными, в памяти и в BL было 55. Однако, работая под управлением Олли, CMP вел себя правильно, как ожидалось, то есть ZF был установлен и прыжок не был выполнен.

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

Отладчик с ошибкой - x64dbg (несмотря на название, это не только для 64-разрядных). Моя сборка уже немного устарела, возможно, исправлена ​​ошибка в последнем снимке.

Спасибо за комментарии всем.


Это было на самом деле ошибка пользователя, а не ошибка в отладчике. На 00838430 была установлена ​​точка останова INT3, о которой я забыл, или, может быть, на мгновение забыл, как работают точки останова программного обеспечения. В любом случае, фактическое содержимое памяти в этом случае было 0xCC, но отладчик показал исходный байт. Таким образом, CMP вел себя так, как должен. Ped7g был прав с первого комментария, что я должен дважды проверить содержимое памяти. Второй тест с другим отладчиком работал правильно только потому, что я не установил точку останова на 00838430.

http://i.imgur.com/iWKad22.jpg

+0

Благодарим вас за решение собственного вопроса. – fuz

 Смежные вопросы

  • Нет связанных вопросов^_^