5
Programa¸
c˜
ao modular
em Linguagem Assembly
(Fam´ılia 51)
jpsousa@fe.up.pt
Conte´
udo
1
Objectivos
1
2
Introdu¸
c˜
ao
1
3
Nomes externos
2
4
Problemas
4
5
Solu¸
c˜
oes
6
1
Objectivos
Consolida¸c˜
ao de conhecimentos sobre a linguagem assembly da fam´ılia 51.
Familiariza-¸c˜
ao com a metodologia de programa¸c˜
ao modular com ˆ
enfase na utiliza¸c˜
ao de segmentos
recoloc´
aveis distribu´ıdos por v´
arios ficheiros.
2
Introdu¸
c˜
ao
Neste gui˜
ao apresentam-se dois exemplos desta metodologia e prop˜
oe-se um conjunto
de problemas onde pode ser aplicada. Estude com cuidado os exemplos apresentados
bem como as considera¸c˜
oes que os acompanham e depois resolva os problemas propostos.
Poder´
a tirar as d´
uvidas que lhe surgirem na sua aula te´
orico-pr´
atica.
3
Nomes externos
Quando a dimens˜
ao e complexidade de um problema s˜
ao consider´
aveis
1´
e recomend´
avel
estruturar a solu¸c˜
ao em m´
odulos de modo a poder reutilizar c´
odigo j´
a desenvolvido. Neste
cen´
ario ´
e frequente a necessidade de aceder a rotinas e vari´
aveis que est˜
ao em diferentes
m´
odulos, ou seja, frequentemente ´
e necess´
ario referenciar nomes simb´
olicos externos. Para
isso existem os qualificadores extrn e public, cuja sintaxe se depreende do exemplo
seguinte, composto por dois m´
odulos – MAIN.A51 com o programa principal e algumas
rotinas e ROT.A51 com outras:
; --- MAIN.A51 ---1 rotinas segment code ; Segmento recoloc´avel em MP
2 vars segment data ; Segmento recoloc´avel em MDI 3
---- 4 rseg vars ; Activa o segmento de dados declarado 0000 5 total: ds 2
0002 6 contador: ds 1 0003 7 teste: ds 1
8
9 public total,contador ; Estes nomes v~ao ser conhecidos de 10 public start ; outros m´odulos
11
12 extrn code(initvars,initsys) ; Rotinas de outros m´odulos 13 extrn data(x,y) ; Vari´aveis definidas noutros 14 extrn xdata(z) ; m´odulos (data=MDI, xdata=MDE) 15 extrn number(SIZE) ; Constantes de outros m´odulos 16
17
---- 18 cseg at 0000h ; Programa principal come¸ca em 0000h 0000 75812F 19 start: mov sp,#2Fh ; Stack come¸ca em 30h
0003 120000 F 20 lcall initvars ; Inicializa vari´aveis 0006 120000 F 21 lcall initsys ; Inicializa resto do sistema 0009 E500 F 22 mov a,x ; Acc fica com o valor da vari´avel x 000B 900000 F 23 mov dptr,#z ; DPTR aponta primeira posi¸c~ao de z
24 ; . 25 ; . 26
---- 27 rseg rotinas ; Activa o segmento rotinas 28
0000 3098FD 29 getch: jnb ri,getch ; Esta rotina ´e local 0003 C298 30 clr ri
0005 E599 31 mov a,sbuf 0007 22 32 ret
33 ; . 34 ; . 35
36 end
1
Embora a complexidade de um problema se possa exprimir em termos formais, nestas aulas ficaremos
Algumas considera¸c˜
oes sobre o m´
odulo MAIN.A51:
1. A declara¸c˜
ao dos nomes total e contador como p´
ublicos (linha 9) permite que eles
sejam conhecidos fora deste m´
odulo. Em consequˆ
encia pode concluir-se que das 3
vari´
aveis declaradas nas linhas 5 a 7, teste ´
e local a este m´
odulo enquanto que
total e contador podem ser acedidas por outros m´
odulos.
2. O mesmo se pode dizer do segmento de c´
odigo identificado pela etiqueta start.
Pelo facto de ter sido declarada p´
ublica (linha 10) ser´
a poss´ıvel referenci´
a-la a partir
de outros m´
odulos.
3. A rotina getch n˜
ao ´
e p´
ublica, ou seja, ´
e local a este m´
odulo. Por este motivo n˜
ao
poder´
a ser chamada de outro m´
odulo.
4. Nas linhas 12 a 15 est´
a a indica¸c˜
ao dos nomes simb´
olicos externos (isto ´
e,
defini-dos noutros m´
odulos como p´
ublicos) que este m´
odulo vai aceder. Para cada um ´
e
necess´
ario indicar o tipo respectivo.
; --- ROT.A51 ---1 public initvars,initsys ; Estes nomes v~ao ser conhecidos de 2 public x,y,z,SIZE ; outros m´odulos
3
4 extrn code(start) ; Rotinas de outros m´odulos 5 extrn data(total,contador) ; Vari´aveis de outros m´odulos 6
7 rotinas segment code ; Segmento recoloc´avel em MP 8 vars segment data ; Segmento recoloc´avel em MDI 9 xvars segment xdata ; Segmento recoloc´avel em MDE 10
0064 11 SIZE equ 100 12
---- 13 rseg vars ; Activa o segmento vars 0000 14 x: ds 1
0001 15 y: ds 1 0002 16 cont: ds 1
17
---- 18 rseg xvars ; Activa o segmento xvars 0000 19 z: ds SIZE
20 21
---- 22 rseg rotinas ; Activa o segmento rotinas 23 0000 E4 24 initvars: clr a 0001 F500 F 25 mov x,a 0003 F500 F 26 mov y,a 0005 F500 F 27 mov contador,a 0007 F500 F 28 mov total,a 0009 F500 F 29 mov total+1,a 30 000B 750064 F 31 mov cont,#SIZE 000E 900000 F 32 mov dptr,#z 33
0017 C3 41 initsys: clr c 0018 E4 42 clr a 43 ; . 44 ; . 0019 22 45 ret 46 47 end
Algumas considera¸c˜
oes sobre o m´
odulo ROT.A51:
1. Repare-se que os nomes que em MAIN.A51 eram extrn aqui s˜
ao public e vice-versa.
2. A etiqueta clean (linha 34) ´
e um nome local. Poder˜
ao existir outros m´
odulos com
o mesmo nome local definido sem que isso provoque conflitos.
Considera¸c˜
oes gerais:
1. Deve existir um segmento de c´
odigo absoluto com in´ıcio no endere¸co 0000h que
garante o arranque do microcontrolador. Nada impede que outros segmentos de
c´
odigo possam ser recoloc´
aveis.
2. Quando se referem nomes simb´
olicos externos ou definidos em segmentos de mem´
oria
recoloc´
aveis, os respectivos endere¸cos aparecem a zero nas listagens (linhas 20 a 23
de MAIN.A51 e linhas 25 a 29, 31 e 32 de ROT.A51). De modo semelhante, os
endere¸cos das instru¸c˜
oes residentes em segmentos de c´
odigo recoloc´
aveis s˜
ao referidos
ao in´ıcio do respectivo segmento (linhas 29 a 32 de MAIN.A51 e linhas 24 a 39 de
ROT.A51). Os verdadeiros endere¸cos podem ser consultados no mapa de s´ımbolos
gerado automaticamente (ficheiro .m51).
4
Problemas
1. Agrupe num ´
unico programa os problemas 7 e 8 do gui˜
ao 2, utilizando a seguinte
estrutura modular:
• Um m´
odulo com as rotinas Upcase e CountBits.
• Um m´
odulo com o programa principal que converte para mai´
usculas um texto
com in´ıcio apontado por R0 e cujo fim ´
e indicado pelo c´
odigo 0 e guarda na
vari´
avel nbits (16 bits), declarada num segmento de dados absoluto, o n´
umero
de bits a um do texto convertido.
2. Desenvolva num m´
odulo totalmente recoloc´
avel com as rotinas addint e subint que
efectuam somas e subtrac¸c˜
oes com operandos de 16 bits sem sinal e as rotinas
addlong e sublong que efectuam somas e subtrac¸c˜
oes com operandos de 32 bits sem
sinal. Os parˆ
ametros de entrada s˜
ao apontados por R0 e R1 e os resultados s˜
ao
guardados nas posi¸c˜
oes do primeiro parˆ
ametro, isto ´
e, apontadas por R0. Considere
que as partes mais significativas das vari´
aveis s˜
ao guardadas nos endere¸cos mais
baixos.
3. Desenvolva um programa que efectue os seguintes c´
alculos:
(a) a = a + b − c com a = 35261, b = 22984 e c = 28354
(b) y = x + y − z com x = 792314842, y = 264104947 e z = 385231684
Utilize comandos do simulador para dar valores `
as vari´
aveis (por exemplo e uint
a=35261 ou e ulong x=792314842).
Referˆ
encias
5
Solu¸
c˜
oes
LOC OBJ LINE SOURCE
1 ;- rots.a51 (reaproveitado) ---2 public Upcase,CountBits
3
4 rotinas segment code 5
---- 6 rseg rotinas 7
0000 F5F0 8 UpCase: mov b,a ; Guarda valor 0002 C3 9 clr c
0003 947A 10 subb a,#’z’ ; Compara com o ASCII do z 0005 500D 11 jnc no ; Salta se for superior 0007 E5F0 12 mov a,b ; Recupera
0009 C3 13 clr c
000A 9461 14 subb a,#’a’ ; Compara com o ASCII do a 000C 4006 15 jc no ; Salta se for inferior 000E E5F0 16 mov a,b ; Recupera
0010 C3 17 clr c
0011 9420 18 subb a,#20h ; Converte 0013 22 19 ret
0014 E5F0 20 no: mov a,b ; Recupera 0016 22 21 ret
22
0017 E6 23 CountBits: mov a,@r0 ; Ler valor
0018 7D00 24 mov r5,#0 ; Contador de bits a um 001A 7C08 25 mov r4,#8 ; Contador de bits 001C 33 26 roda: rlc a ; MSBit para a CY 001D 5001 27 jnc nada
001F 0D 28 inc r5 0020 DCFA 29 nada: djnz r4,roda
0022 ED 30 mov a,r5 ; Resultado em acc... 0023 22 31 ret
32 33
34 end LOC OBJ LINE SOURCE
1 ;- g51.a51 (reaproveitado) ---2 extrn code(Upcase,CountBits) 3 ---- 4 dseg at 50h 0050 5 nbits: ds 2 6 ---- 7 cseg at 0000h 0000 E4 8 clr a 0001 F550 9 mov nbits,a 0003 F551 10 mov nbits+1,a 11
0005 E6 12 next: mov a,@r0 ; Ler posi¸c~ao 0006 6012 13 jz parar ; Se for zero,acaba 0008 120000 F 14 lcall UpCase ; Converte
000B F6 15 mov @r0,a ; Guarda 000C 120000 F 16 lcall CountBits ; Conta
000F 2551 17 add a,nbits+1 ; Acumula ao que j´a tem 0011 F551 18 mov nbits+1,a ; Guarda resultado 0013 5002 19 jnc cont
0015 0550 20 inc nbits
0017 08 21 cont: inc r0 ; Pr´oxima posi¸c~ao 0018 80EB 22 sjmp next ; Continua
23
26
27 end LOC OBJ LINE SOURCE
1 ;- arit.a51 ---2 public addint,addlong,subint,sublong
3
4 rotinas segment code 5
---- 6 rseg rotinas 7
0000 08 8 addlong: inc r0 ; Aponta para 0001 08 9 inc r0 ; o byte menos 0002 08 10 inc r0 ; significativo 0003 09 11 inc r1 ; Aponta para 0004 09 12 inc r1 ; o byte menos 0005 09 13 inc r1 ; significativo 0006 7F04 14 mov r7,#4 ; N´umero de bytes 0008 8004 15 sjmp doadd
16
000A 08 17 addint: inc r0 ; Aponta LSB 000B 09 18 inc r1 ; Aponta LSB 000C 7F02 19 mov r7,#2 ; N´umero de bytes
20
000E C3 21 doadd: clr c 000F E6 22 addlp: mov a,@r0 0010 37 23 addc a,@r1 0011 F6 24 mov @r0,a 0012 18 25 dec r0 0013 19 26 dec r1 0014 DFF9 27 djnz r7,addlp 0016 22 28 ret 29
0017 08 30 sublong: inc r0 ; Aponta para 0018 08 31 inc r0 ; o byte menos 0019 08 32 inc r0 ; significativo 001A 09 33 inc r1 ; Aponta para 001B 09 34 inc r1 ; o byte menos 001C 09 35 inc r1 ; significativo 001D 7F04 36 mov r7,#4 ; N´umero de bytes 001F 8004 37 sjmp dosub
38
0021 08 39 subint: inc r0 ; Aponta LSB 0022 09 40 inc r1 ; Aponta LSB 0023 7F02 41 mov r7,#2 ; N´umero de bytes
42
0025 C3 43 dosub: clr c 0026 E6 44 sublp: mov a,@r0 0027 97 45 subb a,@r1 0028 F6 46 mov @r0,a 0029 18 47 dec r0 002A 19 48 dec r1 002B DFF9 49 djnz r7,sublp 002D 22 50 ret 51 52 end LOC OBJ LINE SOURCE