Por que esse código não foi escrito de uma maneira muito mais simples?

8

Me deparei com uma pergunta enquanto trabalhava em linguagem assembly. Aqui está a pergunta:

Suponha que o bit P2.2 seja usado para controlar uma luz externa e o bit P2.5 uma luz dentro de um edifício. Mostre como acender a luz externa e desligar a interna.

Solução fornecida:

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

Eu apenas senti que faria exatamente o mesmo trabalho para codificar:

SETB P2.2
CLR P2.5

O que há de errado nisso?

İlker Demirel
fonte
2
Talvez apenas didática - mostrando como usar o bit de transporte como um acumulador. Não há vantagem que eu possa ver neste caso em particular. Parece código de montagem 8051.
Spehro Pefhany
@SpehroPefhany Mas até onde eu sei, o registro Acc é usado em alguns casos, pois é o único registro que suporta algumas instruções como DA, RR, RL etc. Não acho que seja esse o caso aqui. Estou errado?
İlker Demirel 01/09
O transporte é um pouco largo. Você pode usá-lo como um acumulador em alguns casos, como avaliação da lógica ladder.
Spehro Pefhany

Respostas:

11

Você está certo em que parece que o código que você mostra é bobo. Talvez qualquer máquina que esteja executando não possa executar operações imediatas para definir bits nas portas de E / S, e é por isso que algo como SETB P2.2 não é possível.

Ainda definindo o bit CY como 1, então ORing qualquer coisa nele é simplesmente bobo. O mesmo vale para definir o bit CY como 0 e depois colocar algo nele. Claramente, o bit CY pode ser copiado diretamente em um bit de E / S, uma vez que o código faz isso. No máximo, devem ser 4 instruções, certamente não 6.

Olin Lathrop
fonte
Então, posso dizer que, se um bit é endereçável por bit, posso usar instruções de bit em qualquer bit, certo?
İlker Demirel 01/09
1
@ Izk: Não necessariamente. Pode haver restrições como as instruções de bit que funcionam apenas em determinados registradores, certas memórias "near" e similares. Sem conhecer o processador, não podemos dizer com certeza se o SETB P2.2 teria sido possível. No entanto, o SETB C seguido pelo MOV P2.2, C, é claramente possível.
Olin Lathrop
1
@OlinLathrop: O processador é quase certamente uma variante 8051, e o conjunto de instruções para esses permitirá que os mesmos locais sejam usados SETB bite CLR bitinstruções como para MOV bit,C. Além disso, ao usar instruções discretas para ler uma porta de E / S, atualizar o valor e gravá-lo, produzirá semântica diferente do uso de instruções de leitura-modificação-gravação, as instruções bit a bit usam a mesma semântica de leitura-modificação-gravação em I / O portas.
Supercat
9

O código é quase certamente para um processador que usa o conjunto de instruções 8051. Nesse processador, a variação de código fornecida teria o mesmo efeito que o original, exceto que seria executada mais rapidamente. Executar "ORL C, P2.2" quando o transporte estiver definido não terá efeito observável, exceto para desperdiçar algum número de ciclos (dois ciclos de CPU totalizando 24 ciclos de clock em um 8051, se bem me lembro; provavelmente um número diferente em algumas outras variantes) . Da mesma forma com a execução de "ANL C, P2.5" quando o transporte estiver livre. Embora possa haver alguns tipos de processador em que uma solicitação para ler alguns locais de E / S tenha algum efeito observável, não acho que nenhum processador do estilo 8051 tenha tido esse comportamento em locais de E / S endereçáveis ​​por bits, menos para bits de P2.

Talvez o objetivo do código fosse demonstrar as instruções ORL C,bite ANL C,bit, mas este parece ser um exemplo estranho para demonstrá-las.

supercat
fonte
6

O código do assembly fornecido é provavelmente gerado pelo compilador. É a versão não otimizada das seguintes instruções C, onde P2_2e P2_5são os objetos endereçáveis ​​por bits:

P2_2 |= 1;
P2_5 &= 0;

Isto pode parecer equivalente a P2_2 = 1;e P2_5 = 0;, mas não é se os registros bit endereçáveis são objetos voláteis. Uma operação de leitura, modificação e gravação em um objeto volátil deve executar a leitura e a gravação, nessa ordem. Isso garante que quaisquer efeitos colaterais da leitura ou gravação do registro realmente ocorram.

Embora eu não conheça nenhum registro endereçável de 8051 bits com efeitos colaterais, um compilador não pode assumir que não existe ou nunca existirá.

D Krueger
fonte
1
Bom argumento sobre possivelmente ser gerado pelo compilador. No entanto, ele move-se então a questão de por que alguém iria escrever P2_2 | = 1 em vez de apenas P2_2 = 1.
Olin Lathrop
3

A diferença real entre eles pode ser sutil.

Na sua resposta simplificada, a lógica é ler a porta, definir ou limpar o valor do bit e, em seguida, gravá-lo novamente na porta. Observe que toda a porta pode ser reescrita aqui.

A solução, por outro lado, usa a instrução de bit MOV, que pode operar de uma maneira bastante diferente.

Sem entrar em detalhes da parte específica usada aqui, é difícil determinar se há uma diferença ou se é importante.

Ou poderia ser apenas o instrutor que decidiu fazer você pensar ... o que é afinal o trabalho dele.

Trevor_G
fonte
0

A única resposta é que o processador não suporta instruções de 1 bit diretamente. No entanto, quando o bit de transporte é usado, ele sabe que apenas um bit está sendo manipulado.

Guill
fonte