Отрицательная операция на языке ассемблера и carryflag
Когда я выполняю отрицательную операцию на A79CDB48h на языке ассемблера, я получаю CF(флаг переноса), который должен быть установлен 1. Может кто-нибудь объяснить, почему это произошло
2 ответа
Смущенный? Понятный.
Я предполагаю, что вы работаете с машиной x86 некоторого разнообразия.
Флаг переноса в этом случае не ведет себя так, как вы ожидаете. Вместо этого он следует этим правилам...
"...Флаг CF установлен в 0, если исходный операнд равен 0; в противном случае он установлен в 1. Флаги OF, SF, ZF, AF и PF устанавливаются в соответствии с результатом....."
Я взял это с этой страницы. Посмотрите в поле "Флаги затронуты".
Я забыл, в каком руководстве Intel это задокументировано, поэтому кто-нибудь, пожалуйста, помогите этому парню со ссылкой.
У них были свои причины для этого, и они позаботились об аномалии, документируя это. На данный момент ваша работа - жить с путаницей и писать код для ее устранения.
Если вы делаете что-то вроде...
Neg Eax ;Negate some value
Jc It_was_positive ;It was a positive number
Jmp It_was_negative ;It was negative
... тогда поменяй Jc
инструкция к одному из подписанных арифметических условных переходов; и предостережение: я не пишу ваш код для вашей конкретной проблемы, так что это может быть совершенно неправильно для вашей насущной необходимости. Проверьте это, прежде чем доверять.
О, предупреждаю о ваших будущих усилиях: другие фишки других компаний определяют поведение флага переноса в соответствии со своими желаниями. Я думаю, что это микрочип; может кто-то еще; без разницы; они разработали свой флаг переноса так, чтобы он работал в точности так же, как другие флаги переноса. то есть 1
а также 0
состояния могут означать прямо противоположное тому, что вы думаете.
Короткая версия: хорошее общее правило: не используйте Jc
а также Jnc
, Вместо этого используйте арифметические условные инструкции.
Во-первых, предполагая, что мы имеем дело с архитектурой x86, она определена так, как указано в справочном руководстве Intel.
IF DEST = 0
THEN CF ← 0;
ELSE CF ← 1;
FI;
DEST ← [– (DEST)]
Вероятная причина этой договоренности заключается в том, что функция может быть реализована как побочный эффект обобщенного сложения / вычитания, как
DEST ← [ TEMP - (DEST) ]
Где TEMP может быть [R/M]
или непосредственный 0, когда код операции - NEG. В качестве побочного эффекта ALU будет вычислять CF и остальные флаги, как если бы операции выполнялись между двумя регистрами общего назначения. Такое расположение просто позволяет повторно использовать дорогостоящее оборудование. Более поздние процессоры просто подтвердили спецификации, хотя реализация не была основана на той же микрокодированной архитектуре.