• Nenhum resultado encontrado

Programação em Linguagem Assembly (Saltos e Subrotinas)

N/A
N/A
Protected

Academic year: 2022

Share "Programação em Linguagem Assembly (Saltos e Subrotinas)"

Copied!
8
0
0

Texto

(1)

Programa¸ c˜ ao em Linguagem Assembly (Saltos e Subrotinas)

Jo˜ ao Paulo Sousa jpsousa@fe.up.pt

Setembro 2005

Conte´ udo

1 Objectivos 2

2 Introdu¸c˜ao 2

3 Ciclos e estruturas de controlo 2

3.1 Ciclosfor() . . . 2

3.2 Ciclosenquanto() . . . 3

3.3 Ciclosrepetir() . . . 3

3.4 Estruturas if then else . . . 4

3.5 Estruturas de escolha m´ultipla . . . 5

4 Chamada e retorno de subrotinas 6

5 Problemas 7

(2)

1 Objectivos

Consolida¸c˜ao de conhecimentos sobre programa¸c˜ao em linguagemassembly da fam´ılia 51. Familiariza¸c˜ao com as instru¸c˜oes de salto e chamada de subrotinas. Utiliza¸c˜ao dastack e dostack pointer.

2 Introdu¸ c˜ ao

Ao contr´ario do que se passa nas linguagens de alto n´ıvel, a linguagemassembly n˜ao disp˜oe mecanismos pr´oprios que conduzam a programar de modo estruturado. Felizmente ´e f´acil implementar algumas estruturas de controlo existentes em linguagens de alto n´ıvel recorrendo a instru¸c˜oes de salto. Estude com cuidado os exemplos apresentados e as considera¸c˜oes que os acompanham bem como um dos livros recomendados [2, sec¸c˜ao 2.4] e depois resolva os problemas propostos.

3 Ciclos e estruturas de controlo

3.1 Ciclos for()

A maneira mais f´acil de controlar a execu¸c˜ao de determinado grupo de instru¸c˜oes um n´umero de vezes conhecido ´e utilizar a instru¸c˜ao DJNZ (decrement and jump if not zero) que admite como operando um registo (djnz Rn,rel8) ou uma vari´avel definida em mem´oria (djnz direct,rel8). Repare-se no seguinte exemplo:

LOC OBJ LINE SOURCE

1 ;====================================================================

2 ; Inicializa¸c~ao de vari´aveis em mem´oria

3 ;

4 ; for(i=0;i<20;i++) {

5 ; temp[i]=0

6 ; }

7 ; tmed=0;

8 ;====================================================================

9

0014 10 SIZE equ 20 ; Tamanho do vector

11

---- 12 dseg at 40h ; Segmento (absoluto) de dados

0040 13 temp: ds SIZE ; Vector temperaturas...

0054 14 tmed: ds 1 ; Temperatura m´edia

15

---- 16 cseg at 0000h ; Segmento (absoluto) de c´odigo

0000 7840 17 mov r0,#temp ; Endere¸co inicial do vector

0002 E4 18 clr a

0003 7F10 19 mov r7,#SIZE ; Tamanho do vector

0005 F6 20 next: mov @r0,a ; Inicializa (limpa) posi¸c~ao apontada

0006 08 21 inc r0 ; Aponta posi¸c~ao seguinte

0007 DFFC 22 djnz r7,next ; Salta se R7 for diferente de zero

0009 F6 23 mov @r0,a ; Inicializa (limpa) tmed

24

25 end

Algumas considera¸c˜oes sobre o exemplo apresentado:

1. O segmento de dados come¸ca no endere¸co 40h (linha 12) e a vari´aveltemp ocupa 20 (14h) bytes (linhas 13 e 10), logo ´e l´ogico que o endere¸co da vari´aveltmed(linha 14) seja 54h.

2. O registo R0 funciona como apontador para o vectortempe deve ser inicialmente carregado com o endere¸co da primeira posi¸c˜ao do vector (linha 17).

3. O inicio do ciclo de limpeza do vector temp´e assinalado com a etiquetanext(linha 20). Fora do ciclo (linha 19) o registo R7, que funciona como contador, ´e inicializado com o n´umero de posi¸c˜oes do vector.

(3)

4. A instru¸c˜aodjnz, de decremento, compara¸c˜ao e salto, ´e codificada em doisbytes: no primeiro est´a o c´odigo da instru¸c˜ao e no segundo adistˆanciaentre o endere¸co dapr´oximainstru¸c˜ao e o endere¸co destino, neste caso, quatrobytespara tr´as. Esta distˆancia, que pode tomar valores de−128 a +127,

´

e expressa numbyte em complemento para dois, o que justifica a representa¸c˜ao FCh (=–4) que se pode constatar na listagem.

5. No fim do ciclo o apontador aponta uma posi¸c˜ao al´em da ´ultima do vectortemp, ou seja, aponta justamente para a vari´aveltmedpelo que (linha 23) basta escrever l´a o valor zero.

3.2 Ciclos enquanto()

Um ciclo deste tipo caracteriza-se por ter o teste de controlo logo no in´ıcio pelo que o conjunto de instru¸c˜oes que encerra pode nunca ser executado. O exemplo seguinte introduz a instru¸c˜ao de salto condicionaljz(jump if accumulator is zero) e o salto incondicionaljmp:

LOC OBJ LINE SOURCE

1 ;====================================================================

2 ; Ciclo enquanto

3 ;

4 ; while(cont!=0) {

5 ; cont--

6 ; }

7 ; cont=100;

8 ;====================================================================

9

---- 10 dseg at 40h ; Segmento (absoluto) de dados

0040 11 cont: ds 1 ; Contador

12

---- 13 cseg at 0000h ; Segmento (absoluto) de c´odigo

14

0000 E540 15 next: mov a,cont ; Teste da

0002 6004 16 jz done ; condi¸c~ao de fecho do ciclo

0004 1540 17 dec cont

0006 80F8 18 jmp next ; Volta ao in´ıcio do ciclo

0008 754064 19 done: mov cont,#100 ; Atribui¸c~ao final 20

21 end

Algumas considera¸c˜oes sobre o exemplo apresentado:

1. O teste de controlo do ciclo ´e feito no in´ıcio de cada itera¸c˜ao (linhas 15 e 16) de modo que se inicialmente a vari´avelcontfor nula, o ciclo n˜ao se realiza nenhuma vez.

2. O salto na linha 18 ´e essencial para garantir a repeti¸c˜ao do teste no in´ıcio de cada itera¸c˜ao. A prop´osito deste salto conv´em esclarecer quejmpn˜ao ´e uma instru¸c˜ao no sentido estrito da palavra, mas sim uma instru¸c˜aovirtual, pr´opria do assemblador da Keil, que este transformaautomatica- mentenuma de trˆes instru¸c˜oes reais: sjmp(short jump),ajmp(absolute jump) ouljmp(long jump) consoante adistˆancia ao destino especificada no salto em quest˜ao. Aqui, a codifica¸c˜ao resultante (80h, linha 18) corresponde, como seria de esperar atendendo `a distˆancia, `a da instru¸c˜aosjmp.

3. Mais uma vez a codifica¸c˜ao das instru¸c˜oes de salto utilizadas neste exemplo ´e feita em doisbytes:

o primeiro corresponde ao c´odigo da instru¸c˜ao propriamente dita e o segundo `a distˆancia entre o endere¸co da pr´oxima instru¸c˜ao e o endere¸co destino. No primeiro salto (linha 16) essa distˆancia

´

e de quatro bytes para a frente e no segundo ´e de oito bytes para tr´as (a que corresponde, em complemento para dois, a representa¸c˜ao F8h).

3.3 Ciclos repetir()

Um ciclo deste tipo caracteriza-se por ter o teste de controlo no fim de cada itera¸c˜ao pelo que o conjunto de instru¸c˜oes que encerra ´e sempre executado pelo menos uma vez. Repare-se no seguinte exemplo que

(4)

introduz a instru¸c˜aojnz(jump if accumulator is not zero):

LOC OBJ LINE SOURCE

1 ;====================================================================

2 ; Ciclo repetir

3 ;

4 ; do {

5 ; cont--

6 ; } while(cont!=0);

7 ; cont=100;

8 ;====================================================================

9

---- 10 dseg at 40h ; Segmento (absoluto) de dados

0040 11 cont: ds 1 ; Contador

12

---- 13 cseg at 0000h ; Segmento (absoluto) de c´odigo

14

0000 1540 15 next1: dec cont

0002 E540 16 mov a,cont ; Teste da

0004 70FA 17 jnz next1 ; condi¸c~ao de fecho do ciclo

0006 754064 18 mov cont,#100 ; Atribui¸c~ao final

19 20

21 ; ou ent~ao, de forma ainda mais resumida 22

0009 D540FD 23 next2: djnz cont,next2 ; Decrementa, testa e repete

000C 754064 24 mov cont,#100 ; Atribui¸c~ao final

25

26 end

Algumas considera¸c˜oes sobre o exemplo apresentado:

1. O teste de controlo do ciclo ´e feito no fim de cada itera¸c˜ao (linhas 16 e 17) por isso, ainda que a vari´avelcont seja inicialmente nula, realiza-se sempre pelo menos uma itera¸c˜ao do ciclo. Neste exemplo concreto esse caso particular daria at´e origem a que se efectuassem 256 itera¸c˜oes j´a que, ap´os a primeira, a vari´avelcontpassaria de zero para 255 e o ciclo s´o pararia quandocontvoltasse a zero novamente.

2. A instru¸c˜aodjnz (linha 23) permite, neste caso particular, uma codifica¸c˜ao alternativa muito efi- ciente.

3.4 Estruturas if then else

As instru¸c˜oes de salto permitem uma implementa¸c˜ao confort´avel deste tipo de estruturas nos programas escritos emassembly. O exemplo seguinte introduz as instru¸c˜oesljmp(long jump) ecjne(compare and jump if not equal).

LOC OBJ LINE SOURCE

1 ;====================================================================

2 ; Teste de valores de 16 bits e de valores n~ao nulos

3 ;

4 ; if(val==0) {

5 ; state++;

6 ; cont=MAXCONT;

7 ; }

8 ; else {

9 ; if(state==12)

10 ; state--;

11 ; }

12 ;====================================================================

13

3A98 14 MAXCONT equ 15000

15

---- 16 dseg at 40h

0040 17 val: ds 2 ; Ocupa 2 bytes

0042 18 cont: ds 2 ; Ocupa 2 bytes

0044 19 state: ds 1 ; Ocupa apenas 1 byte

20

---- 21 cseg at 0000h

0000 E540 22 mov a,val ; Pega no MSB e

(5)

0002 4541 23 orl a,val+1 ; conjuga com o LSB

0004 600A 24 jz zero ; Salta se LSB=MSB=0

25

0006 740C 26 mov a,#12

0008 B5440D 27 cjne a,state,done ; Compara state com 12, salta se diferente

000B 1544 28 dec state ; Faz state--

000D 020018 29 ljmp done

30

0010 0544 31 zero: inc state ; Faz state++

0012 75423A 32 mov cont,#high(MAXCONT) ; Guarda MSB de MAXCONT 0015 754398 33 mov cont+1,#low(MAXCONT) ; Guarda LSB de MAXCONT

0018 34 done:

35

36 end

Algumas considera¸c˜oes sobre o exemplo apresentado:

1. Repare-se na declara¸c˜ao da vari´avelval(linha 17): uma vez que ocupa doisbyteso teste efectuado (linhas 22, 23 e 24) deve incluir ambos.

2. Nas linhas 32 e 33 foram utilizados dois operadores suportados pelo assemblador da Keil (high e low) que calculam, respectivamente, a metade mais significativa e menos significativa de um valor de 16 bits.

3. A instru¸c˜ao de salto incondicionalljmp(linha 29) n˜ao era aqui estritamente necess´aria pois, aten- dendo ao endere¸co destino do salto, bastaria utilizar a instru¸c˜aosjmp. Ela est´a aqui por causa da sua tradu¸c˜ao em c´odigo m´aquina: dos trˆesbytes gerados o primeiro (02h) ´e o c´odigo da instru¸c˜ao propriamente dita enquanto que os dois seguintes (0018h) representam o endere¸codestino e n˜ao a distˆancia do salto. Poderia ter sido utilizada a instru¸c˜ao virtual gen´erica jmpque teria neste caso como tradu¸c˜ao os c´odigos da instru¸c˜aosjmp.

3.5 Estruturas de escolha m´ ultipla

A instru¸c˜ao de compara¸c˜aocjnepermite tamb´em implementar estruturas de escolha m´ultipla semelhantes

`

as que existem em linguagens de alto n´ıvel. Repare-se no exemplo seguinte:

LOC OBJ LINE SOURCE

1 ;===============================================================

2 ; Escolha m´ultipla

3 ;

4 ; switch (op) {

5 ; case 1: pin=10;break;

6 ; case 2: pin=50;break;

7 ; case 3: pin=250;break;

8 ; default: pin=0;

9 ; }

10 ;===============================================================

11

---- 12 dseg at 40h

0040 13 op: ds 1

0041 14 pin: ds 1

15

---- 16 cseg at 0000h

0000 E540 17 mov a,op

0002 B40104 18 cjne a,#1,Not1 ; Compara com 1

0005 740A 19 mov a,#10

0007 800F 20 sjmp done

0009 B40204 21 Not1: cjne a,#2,Not2 ; Compara com 2

000C 7432 22 mov a,#50

000E 8008 23 sjmp done

0010 B40304 24 Not2: cjne a,#3,Not3 ; Compara com 3

0013 74FA 25 mov a,#250

0015 8001 26 sjmp done

0017 E4 27 Not3: clr a ; Default...

0018 F541 28 done: mov pin,a

29

30 end

Algumas considera¸c˜oes sobre o exemplo apresentado:

(6)

1. A compara¸c˜ao (linhas 18, 21 e 24) n˜ao estraga o registo acumulador pelo que (linha 17) basta carreg´a-lo uma vez.

2. Novamente se nota nos c´odigos da instru¸c˜ao de compara¸c˜ao e salto (linhas 18, 21 e 24) adistˆancia entre o endere¸co da pr´oxima instru¸c˜ao e o endere¸co destino do salto, quatrobytes nos trˆes casos deste exemplo.

3. A instru¸c˜ao mov final (linha 28) completa a execu¸c˜ao. ´E sempre executada qualquer que seja a escolha feita.

4 Chamada e retorno de subrotinas

As instru¸c˜oes de chamada de subrotinas1contribuem decisivamente para garantir uma boa estrutura dos programas, ao permitirem dividir uma tarefa complexa em tarefas mais simples, cada uma executada por uma rotina que em devido tempo ser´a chamada. O exemplo seguinte apresenta as instru¸c˜oes de chamada lcalleacall, a instru¸c˜ao de retorno rete a instru¸c˜aonop(no operation).

LOC OBJ LINE SOURCE

1 ;====================================================================

2 ; Atraso configur´avel

3 ;

4 ; delay(n) { 5 ; for(i=n;i<0;i--);

6 ; }

7 ;

8 ; delay(50);

9 ; delay(100);

10 ;====================================================================

11

---- 12 cseg at 0000h

0000 7F32 13 mov r7,#50

0002 120080 14 lcall delay ; delay(50)

0005 7F64 15 mov r7,#100

0007 1180 16 acall delay ; delay(100)

0009 80FE 17 stop: sjmp stop

18

---- 19 cseg at 0080h

0080 00 20 delay: nop ; N~ao faz nada

0081 00 21 nop ; a n~ao ser gastar algum tempo

0082 DFFC 22 djnz r7,delay ; Repete R7 vezes

0084 22 23 ret

24

25 end

Algumas considera¸c˜oes sobre o exemplo apresentado:

1. A codifica¸c˜ao da instru¸c˜aolcall(linha 14) ´e bastante mais simples e directa do que a da instru¸c˜ao acall (linha 16). Naquela aparece de forma evidente o endere¸co destino enquanto nesta parte do endere¸co ´e incorporada no c´odigo da instru¸c˜ao [1, p´aginas 17 e 36].

2. Poderia ter sido utilizada a instru¸c˜ao virtual gen´erica call para substituir as instru¸c˜oes lcall e acall. Atendendo `a proximidade da rotina, a instru¸c˜ao virtual seria traduzida, em ambos os casos, como se tratasse de uma instru¸c˜aoacall.

3. A instru¸c˜ao de salto (linha 17) ´e necess´aria para encravar o programa, caso contr´ario depois de executada a instru¸c˜ao da linha 16, a subrotina seria novamente executada mas no fim a stack ficaria corrompida por ter sido executado um retsem previamente ter sido executado um acall oulcall.

1 Os termosrotina esubrotina ser˜ao usados indistintamente para especificar um conjunto de instru¸oes que executam uma tarefa espec´ıfica no contexto da resolu¸ao de um problema mais abrangente.

(7)

5 Problemas

Apresentam-se de seguida alguns problemas que requerem a utiliza¸c˜ao de instru¸c˜oes de salto e chamada de subrotinas.

1. Escreva um programa que calculet=

19

X

i=0

y[i] supondo que os elementos do vector:

(a) s˜ao todos inferiores a 13, (b) s˜ao todos inferiores a 256.

Declare as vari´aveis num segmento de dados absoluto com in´ıcio em 40h.

2. Traduza `a m˜ao, para c´odigo m´aquina, as duas solu¸c˜oes do problema anterior.

3. Escreva uma rotina que calcule a soma (efectuada sem considerar eventuais transportes) dos con- te´udos de uma zona de mem´oria com 32 bytes de comprimento e in´ıcio apontado pelo registo R0.

O resultado deve ficar no acumulador. Escreva um programa que chame essa rotina para somar os conte´udos da zona de mem´oria com in´ıcio no endere¸co 30h.

4. Escreva uma rotina que calcule o valor m´ınimo de uma zona de mem´oria com in´ıcio apontado pelo registo R0 e comprimento indicado no registo R7. No fim o m´ınimo deve ficar em R7.

5. Escreva a rotinatestvalque testa se o valor contido no acumulador ´e positivo, nulo ou negativo e incrementa, respectivamente, as vari´aveisnp,nzenn.

6. Considere o vectorvv[ ], com 50 elementos de umbyte cada, representados em complemento para dois. Com base na rotina desenvolvida no problema anterior escreva um programa que comece por fazernp=nz=nn= 0 e de seguida conte quantos elementos positivos, nulos e negativos existem no vector. Declare o vector e as vari´aveis num segmento de dados absoluto com in´ıcio em 60h.

7. Escreva um programa que implemente na vari´avelcont– definida num segmento de dados absoluto com in´ıcio em 30h – um contador BCD (binary coded decimal) de dois d´ıgitos. Considere os seguintes casos:

(a) contagem crescente: 0, 1, 2, . . . , 99, 0, 1, . . . ,

(b) contagem decrescente: 99, 98, . . . , 2, 1, 0, 99, 98, . . . .

Sugest˜ao: consulte o manual de programa¸c˜ao [1, p´agina 27] para perceber como funciona a instru¸c˜ao da(decimal adjust) e utilize-a.

8. Suponha j´a existente a rotina upcase que converte para mai´uscula a letra min´uscula contida no acumulador devolvendo o resultado da convers˜ao tamb´em no acumulador.

(a) Escreva um programa que, recorrendo a essa rotina, converta para mai´usculas um texto com in´ıcio apontado por R0 e cujo fim ´e indicado pelo c´odigo 0.

(b) Escreva a rotina upcase.

9. Apresente duas rotinas diferentes (cjne, movc) para converter o valor contido no acumulador de acordo com a tabela 1. O resultado deve vir no acumulador.

O valor 0 1 2 3

E convertido em´ 100 232 166 250 Tabela 1: Convers˜ao de valores

(8)

10. Suponha j´a existente a rotina countbits que conta o n´umero de bits a um da posi¸c˜ao de mem´oria apontada por R0, devolvendo o resultado no acumulador.

(a) Escreva um programa que, recorrendo a essa rotina, conte o n´umero de bits a um de uma zona de mem´oria com in´ıcio apontado pelo registo R0 e comprimento indicado no registo R7. O resultado deve ficar na vari´avelnbits, declarada num segmento de dados absoluto.

(b) Escreva a rotinacountbits.

Referˆ encias

[1] Philips semiconductors;80C51 family programmer’s guide and instruction set; Setembro de 1997.

[2] Yeralan, Senser and Ahluwalia, Ashutosh; Programming and Interfacing the 8051 Microcontroller;

Addison Wesley, 1995; ISBN 0–201–63365–5.

Referências

Documentos relacionados

By interpreting equations of Table 1, it is possible to see that the EM radiation process involves a periodic chain reaction where originally a time variant conduction

O desenvolvimento desta pesquisa está alicerçado ao método Dialético Crítico fundamentado no Materialismo Histórico, que segundo Triviños (1987)permite que se aproxime de

Para preparar a pimenta branca, as espigas são colhidas quando os frutos apresentam a coloração amarelada ou vermelha. As espigas são colocadas em sacos de plástico trançado sem

Nessa situação temos claramente a relação de tecnovívio apresentado por Dubatti (2012) operando, visto que nessa experiência ambos os atores tra- çam um diálogo que não se dá

A Lei nº 2/2007 de 15 de janeiro, na alínea c) do Artigo 10º e Artigo 15º consagram que constitui receita do Município o produto da cobrança das taxas

•   O  material  a  seguir  consiste  de  adaptações  e  extensões  dos  originais  gentilmente  cedidos  pelo 

Podem treinar tropas (fornecidas pelo cliente) ou levá-las para combate. Geralmente, organizam-se de forma ad-hoc, que respondem a solicitações de Estados; 2)

O destaque é dado às palavras que abrem signi- ficados e assim são chaves para conceitos que fluem entre prática poética na obra de arte e sua reflexão em texto científico..