Почему этот код не был написан намного проще?

8

Я сталкивался с вопросом, работая над языком ассемблера. Вот вопрос:

Предположим, что бит P2.2 используется для управления наружным освещением, а бит P2.5 - освещением внутри здания. Покажите, как включить внешний свет и выключить внутренний.

Решение дано:

SETB C            ; CY = 1
ORL C, P2.2       ; CY = P2.2 ORed w/ CY
MOV P2.2, C       ; turn it on if not on
CLR C             ; CY = 0
ANL C, P2.5       ; CY = P2.5 ANDed w/P2.5
MOV P2.5,C        ; turn it off if not off

Я просто чувствовал, что он будет делать ту же работу, чтобы кодировать:

SETB P2.2
CLR P2.5

Что в этом плохого?

Илкер Демирель
источник
2
Может быть, просто дидактика, показывающая, как использовать бит переноса в качестве аккумулятора. Там нет никакого преимущества, которое я вижу в этом конкретном случае. Это похоже на код сборки 8051.
Спехро Пефхани
@SpehroPefhany Но, насколько мне известно, регистр Acc используется в некоторых случаях, поскольку он является единственным регистром, который поддерживает некоторые инструкции, такие как DA, RR, RL и т. Д. Я не думаю, что это так. Я ошибаюсь?
Илкер Демирель
Керри шириной в один бит. Возможно, вы захотите использовать его в качестве аккумулятора в некоторых случаях, например, при оценке релейной логики.
Спехро Пефхани

Ответы:

11

Вы правы в том, что кажется, код, который вы показываете, глупый. Возможно, какая бы машина ни работала на этом компьютере, она не может выполнять немедленные операции по установке битов на портах ввода / вывода, и именно поэтому что-то вроде SETB P2.2 невозможно.

Все еще устанавливая бит CY на 1, тогда ИЛИ что-либо в это просто глупо. То же самое касается установки бита CY на 0, а затем ввода чего-то в него. Ясно, что бит CY может быть непосредственно скопирован в бит вывода ввода / вывода, поскольку код делает это. Максимум это должно быть 4 инструкции, а не 6.

Олин Латроп
источник
Таким образом, я могу сказать, что если бит является адресуемым битом, мне разрешено использовать битовые инструкции для любого бита, верно?
Илкер Демирель
1
@ Ilk: не обязательно. Могут быть ограничения, например, битовые инструкции работают только с определенными регистрами, определенной «ближней» памятью и т.п. Не зная процессора, мы не можем точно сказать, был бы возможен SETB P2.2. Однако, SETB C, за которым следует MOV P2.2, C, вполне возможно.
Олин Латроп
1
@OlinLathrop: Процессор почти наверняка представляет собой вариант 8051, и набор инструкций для них позволяет использовать те же места SETB bitи CLR bitинструкции, что и для MOV bit,C. Кроме того, при использовании дискретных инструкций для чтения порта ввода-вывода, обновления значения и обратной записи получится другая семантика при использовании инструкций чтения-изменения-записи, все побитовые инструкции используют одну и ту же семантику чтения-изменения-записи в I / O порты.
суперкат
9

Код почти наверняка предназначен для процессора, использующего набор команд 8051. На этом процессоре изменение кода, которое вы предоставляете, будет иметь тот же эффект, что и оригинал, за исключением того, что оно будет работать быстрее. Выполнение «ORL C, P2.2» при установленном переносе не будет иметь никакого наблюдаемого эффекта, кроме как потратить некоторое количество циклов (два цикла ЦП на 2451 такта на 8051, если я правильно помню; вероятно, другое число на некоторых других вариантах) , Аналогично с выполнением «ANL C, P2.5», когда перенос очищен. Хотя могут быть некоторые типы процессоров, в которых запрос на считывание некоторых местоположений ввода-вывода будет иметь некоторый наблюдаемый эффект, я не думаю, что какой-либо процессор в стиле 8051 когда-либо имел такое поведение для любых бито-адресуемых расположений ввода-вывода, очень меньше для битов P2.

Возможно , цель кодекса было продемонстрировать ORL C,bitи ANL C,bitинструкции, но это кажется странным , например , чтобы продемонстрировать их.

Supercat
источник
6

Данный код ассемблера, вероятно, генерируется компилятором. Это неоптимизированная версия следующих операторов C, где P2_2и P2_5являются объектами с битовой адресацией:

P2_2 |= 1;
P2_5 &= 0;

Это может показаться эквивалентным P2_2 = 1;и P2_5 = 0;, но это не так, если регистры с битовой адресацией являются энергозависимыми объектами. Операция чтения-изменения-записи в энергозависимом объекте должна выполнять чтение и запись в указанном порядке. Это гарантирует, что любые побочные эффекты от чтения или записи в регистре действительно происходят.

Хотя я не знаю ни одного 8051-битового адресуемого регистра с побочными эффектами, компилятор не может предположить, что его нет или никогда не будет.

Д Крюгер
источник
1
Хороший вопрос о возможности генерации компилятором. Однако затем переносится вопрос, почему кто-то написал бы P2_2 | = 1 вместо просто P2_2 = 1.
Олин Латроп
3

Реальная разница между ними может быть тонкой.

В вашем упрощенном ответе логика считывает порт, устанавливает или сбрасывает значение бита и затем записывает его обратно в порт. Обратите внимание, что весь порт может быть переписан здесь.

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

Не вдаваясь в детали конкретной детали, используемой здесь, трудно определить, есть ли разница или имеет значение.

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

Trevor_G
источник
0

Единственный ответ - процессор не поддерживает 1-битные инструкции напрямую. Однако, когда используется бит переноса, он знает, что манипулируется только одним битом.

Guill
источник