Outils
Simulateur 8080 : https://www.sim8085.com
Création d’un fichier binaire : https://www.asm80.com/
Simulateur ALTAIR 8800 : https://s2js.com/altair/sim.html
Tous les codes (00.MEM = 3n+1, 01.MEM = n/2, 02.MEM = pair/impair + saut, 03.MEM = avec temps de vol, 04.MEM = avec maximum, 16bits.bin = version 16 bits) : https://uabox.univ-angers.fr/s/o96B5MEfeQAcXLA
Chargement d’une bande perforée : https://youtu.be/qv5b1Xowxdk?feature=shared&t=235
Calcul de 3n+1
Mettre une valeur N en 80h puis lancer le programme ci-dessous
Lire en 80h la valeur 3N+1 (modulo 256)
HEXA : 3A80004787803C32800076
Programme source :
LDA 80h
MOV B, A
ADD A
ADD B
INR A
STA 80h
HLT
Programme objet :
3A 80 00 LDA 80h
47 MOV B, A
87 ADD A
80 ADD B
3C INR A
32 80 00 STA 80h
76 HLT
Division par 2
Mettre une valeur N en 80h puis lancer le programme ci-dessous
Lire en 80h la valeur ENT(N/2)
HEXA : 373F3E1B1F32800076
Programme source :
STC
CMC
MVI A, 27
RAR
STA 80h
HLT
Sauts avec tests pair ou impair
HEXA : 3A800047FE01CA2100E60178CA180087803C328000C30000373F1F328000C3000076
Programme source :
loop: LDA 80h
MOV B, A
CPI 1
JZ fin
ANI 1
MOV A, B
JZ pair
ADD A
ADD B
INR A
STA 80h
JMP loop
pair: STC
CMC
RAR
STA 80h
JMP loop
fin: HLT
Version 1 avec temps de vol uniquement
HEXA : 3E003281 003A8000 47FE01CA 2E003A81 003C3281 0078E601 78CA2500 87803C32 8000C305 00373F1F 328000C3 050076
Programme source :
MVI A, 0
STA 81h
loop: LDA 80h
MOV B, A
CPI 1
JZ fin
LDA 81h
INR A
STA 81h
MOV A, B
ANI 1
MOV A, B
JZ pair
ADD A
ADD B
INR A
STA 80h
JMP loop
pair: STC
CMC
RAR
STA 80h
JMP loop
fin: HLT
Version 2 avec temps de vol et maximum
HEXA : 3E003281 003A8000 3282003A 800047FE 01CA4000 3A81003C 32810078 E60178CA 37008780 3C328000 473A8200 B8D20B00 78328200 C30B0037 3F1F3280 00C30B00 76
Programme source :
MVI A, 0
STA 81h
LDA 80h
STA 82h
loop: LDA 80h
MOV B, A
CPI 1
JZ fin
LDA 81h
INR A
STA 81h
MOV A, B
ANI 1
MOV A, B
JZ pair
ADD A
ADD B
INR A
STA 80h
MOV B, A
LDA 82h
CMP B
JNC loop
MOV A, B
STA 82h
JMP loop
pair: STC
CMC
RAR
STA 80h
JMP loop
fin: HLT
Version 16 bits
Mettre la partie basse de N en 80h et la partie haute en 81h. Par exemple pour 27 : 00 011 011 en 80h et 00 000 000 en 81h
Lire le temps de vol en 84h et le maximum aux adresses 82h (partie basse) et 83h (partie haute)
2A 80 00 LHLD 80H ; Initialisation des mémoires 82h à 84h
22 82 00 SHLD 82H ; copie de 80-81h vers 82-83h
21 84 00 LXI H, 84H ;
36 00 MVI M, 0 ; Temps de vol = 0
21 81 00 collatz: LXI H, 81H
7E MOV A, M ; Si la valeur haute
B7 ORA A ; n'est pas nulle
C2 1A 00 JNZ parity ; On va tester la parité
2B DCX H ; sinon,
7E MOV A, M ; Si la valeur basse
FE 01 CPI 1 ; vaut 1
CA 5D 00 JZ fin ; on arrête le programme
21 84 00 parity:LXI H, 84H
34 INR M ; temps de vol augmente de +1
21 80 00 LXI H, 80H
7E MOV A, M
5F MOV E, A ; que l'on stocke dans E
E6 01 ANI 1 ; Si Z = 0
CA 3A 00 JZ pair ; C'est un nombre pair
23 INX H
56 MOV D, M
D5 PUSH D
E1 POP H ; HL = DE
29 DAD H ; HL = 2HL
19 DAD D ; HL = 3HL
23 INX H ; HL = 3HL + 1
22 80 00 SHLD 80h ; Nouvelle valeur en 80h
E5 PUSH H
D1 POP D ; On la stocke dans DE
CD 46 00 CALL maxi ; Sous-routine maxi
C3 0B 00 JMP collatz ; Retour à collatz
23 pair: INX H ; Si le nombre est pair
AF XRA A ; Carry = 0
7E MOV A, M ; Division par 2
1F RAR ; de la partie haute
77 MOV M, A
2B DCX H
7E MOV A, M ; division par 2 de la partie basse
1F RAR ; avec ajout éventuel de C à gauche
77 MOV M, A ;
C3 0B 00 JMP collatz ; Retour à collatz
2A 82 00 maxi: LHLD 82H ;
7A MOV A, D ; Récup partie haute du max
BC CMP H ; si égalité des parties hautes
CA 52 00 JZ unite ; tester les unités
D2 58 00 JNC change ; si retenue le max a été dépassé
C9 RET ; sinon ne rien faire
7B unite: MOV A, E ; test des unités
BD CMP L ; si une retenue
DA 58 00 JC change ; le max est dépassé
C9 RET ; retour
EB change: XCHG ; HL = DE
22 82 00 SHLD 82H ; que l'on place en 82h
C9 RET
76 fin: HLT
Résultats à obtenir aux adresses 82-83h et 84h
00 010 000 en 82h (partie basse) et 00 100 100 en 83h (haut)
parseInt('0010010000010000',2)
9232
01 101 111 à l'adresse 84h :
parseInt('01101111',2)
111
Résultats pour N = 639
>>> bin(639)
'0b1001111111'
Il faut donc mettre 01 111 111 à l'adresse 80h et 10 à l'adresse 81h
On lance le programme et on trouve :
Adresse 82h : 00 110 100
Adresse 83h : 10 100 010
Le maximum vaut donc :
>>> int('1010001000110100',2)
41524
Et le temps de vol est à l'adresse 84h : 10 000 011
>>> int('10000011',2)
131