Lösningar på problemen i kapitel 4 i den fullständiga onlinekursen i datavetenskaplig databas och internetkarriär från början

Losningar Pa Problemen I Kapitel 4 I Den Fullstandiga Onlinekursen I Datavetenskaplig Databas Och Internetkarriar Fran Borjan



Problem och deras lösningar

1) Skriv ett assembly-språkprogram som börjar på $0200 för 6502 µP och lägger till de osignerade numren för 2A94 H (lägg till) till 2ABF H (augend). Låt ingångarna och utgångarna finnas i minnet. Ta också fram det sammansatta programdokumentet för hand.







Lösning:



CLC
LDA $0213
ADC $0215
STA $0217
LDA $0214
ADC $0216
STA $0218



Sammansatt program:





2) Skriv ett assemblerspråksprogram som börjar på $0200, för 6502 µP, och subtraherar de osignerade talen, 1569 H (subtrahend) från 2ABF H (minuend). Låt ingångarna och utgångarna finnas i minnet. Ta även fram det sammansatta programdokumentet, för hand.



Lösning:

SEC
LDA $0213
SBC $0215
STA $0217
LDA $0214
SBC $0216
STA $0218

Sammansatt program:

3) Skriv ett assemblerspråksprogram för 6502 µP som räknas upp från $00 till $09 med hjälp av en loop. Programmet bör börja på $0200. Ta också fram det sammansatta programdokumentet för hand.

Lösning:

LDA #$09
STA $0220 ; för att jämföra X och $09
LDX #$00
slinga INX
CPX $0220
BNE-slinga

Sammansatt program:

4) Skriv ett assemblerprogram som börjar på $0200 för 6502 µP. Programmet har två subrutiner. Den första subrutinen lägger till de osignerade numren för 0203 H (augend) och 0102 H (lägg till). Den andra subrutinen adderar summan från den första subrutinen som är 0305 H till 0006 H (augend). Det slutliga resultatet lagras i minnet. Ring den första subrutinen som är FSTSUB och den andra subrutinen som är SECSUB. Låt in- och utgångarna finnas i minnet. Ta också fram det sammansatta programdokumentet för hela programmet för hand.

Lösning:

SECSUB CLC
LDA $021A
ADC $0234
STA $0236
LDA $021 miljarder
ADC $0235
STA $0237
RTS

FSTSUB CLC
LDA $0216
ADC $0218
STA $021A
LDA $0217
ADC $0219
STA $021B
RTS

JSR FSTSUB

Sammansatt program:

5) Med tanke på att en ¯IRQ hanteraren lägger till $02 till $01 vid ackumulatorn som kärnhantering medan ¯NMI utfärdas, och kärnhanteringen för ¯NMI lägger till $05 till $04 vid ackumulatorn, skriv ett assemblerspråk för båda hanterarna inklusive deras samtal. Uppmaningen till ¯IRQ hanteraren ska vara på adressen $0200. De ¯IRQ hanteraren bör börja på adressen $0300. De ¯NMI hanteraren bör börja på adressen $0400. Resultatet av ¯IRQ hanteraren bör placeras på adressen $0500, och resultatet av ¯NMI hanteraren ska placeras på adressen $0501.

Lösning:

NMISR PHA; NMI-rutinen börjar här på $0400-adressen
PHX
PHY
;
LDA #$04
ADC #$05
STA $0501
;
LAGER
PLX
PLA
RTI

ISR PHA; denna instruktion finns på $0300-adressen
PHX
PHY
;
LDA #$01
ADC #$02
; JMP NMISR : kommenterade eftersom det inte är en del av rutinen
STA $0500 ; kommer att gå till stack
;
LAGER
PLX
PLA
RTI
;
JMP ISR ; denna instruktion finns på $0200-adressen

6) Förklara kort hur BRK-instruktionen används för att producera mjukvaruavbrottet i en 65C02-dator.

Lösning:

Det huvudsakliga sättet att få ett mjukvaruavbrott för 65C02 µP är att använda den implicita adressinstruktionen BRK. Antag att huvudprogrammet körs och att det stöter på BRK-instruktionen. Från den punkten ska adressen till nästa instruktion i PC:n skickas till stacken när den aktuella instruktionen slutförs. En subrutin för att hantera programvaruinstruktionen bör anropas härnäst. Denna avbrottssubrutin bör skjuta A-, X- och Y-registerinnehållet till stacken. Efter att kärnan av subrutinen exekveras, bör innehållet i A-, X- och Y-registren dras tillbaka från stacken till deras register av den fullbordande subrutinen. Det sista uttalandet i rutinen är RTI. PC-innehållet dras också tillbaka från stacken till PC:n, automatiskt på grund av RTI.

7) Skapa en tabell som jämför och kontrasterar en normal subrutin med en avbrottsservicerutin.

Lösning:

8) Förklara kortfattat de huvudsakliga adresseringslägena för 65C02 µP givet assemblerspråksinstruktionsexemplen.

Lösning:

Varje instruktion för 6502 är en byte, följt av noll eller fler operander.

Omedelbart adresseringsläge
Med det omedelbara adresseringsläget, efter operanden, är värdet och inte en minnesadress. Värdet måste föregås av #. Om värdet är hexadecimalt måste '#' följas av '$'. De omedelbara adresseringsinstruktionerna för 65C02 är: ADC, AND, BIT, CMP, CPX, CPY, EOR, LDA, LDX, LDY, ORA, SBC. Läsaren bör konsultera dokumentationen för 65C02 µP för att veta hur man använder instruktionerna som listas här och som inte har förklarats i detta kapitel. En exempelinstruktion är:

LDA #77 USD

Absolut adresseringsläge
Med det absoluta adresseringsläget finns det en operand. Denna operand är adressen till värdet i minnet (vanligtvis i hexadecimal eller en etikett). Det finns 64K10 = 65,53610 minnesadresser för 6502 µP. Vanligtvis finns enbytevärdet på en av dessa adresser. De absoluta adresseringsinstruktionerna för 65C02 är: ADC, AND, ASL, BIT, CMP, CPX, CPY, DEC, EOR, INC, JMP, JSR, LDA, LDX, LDY, LSR, ORA, ROL, ROR, SBC, STA , STX, STY, STZ, TRB, TSB. Läsaren bör konsultera dokumentationen för 65C02 µP för att veta hur man använder instruktionerna som listas här samt för resten av adresseringslägena som inte har förklarats i detta kapitel. En exempelinstruktion är:

DE ÄR $1234

Underförstått adresseringsläge
Med det implicita adresseringsläget finns det ingen operand. Alla inblandade µP-register antyds av instruktionen. De underförstådda adresseringsinstruktionerna för 65C02 är: BRK, CLC, CLD, CLI, CLV, DEX, DEY, INX, INY, NOP, PHA, PHP, PHX, PHY, PLA, PLP, PLX, PLY, RTI, RTS, SEC , SED, SEI, TAX, TAY, TSX, TXA, TXS, TYA. En exempelinstruktion är:

DEX: Minska X-registret med en enhet.

Relativt adresseringsläge
Den relativa adresseringsmoden behandlar endast greninstruktioner. Med relativ adresseringsläge finns det bara en operand. Det är ett värde från -12810 till +12710. Detta värde kallas en offset. Baserat på tecknet adderas eller subtraheras detta värde från nästa instruktion i Programräknaren till resultatet i adressen för den avsedda nästa instruktionen. De relativa adresslägesinstruktionerna är: BCC, BCS, BEQ, BMI, BNE, BPL, BRA, BVC, BVS. Instruktionsexemplen är:

BNE $7F : (gren om Z = 0 i statusregistret, P)

som lägger till 127 till den aktuella programräknaren (adress att exekvera) och börjar exekvera instruktionen på den adressen. Liknande:

BEQ $F9 : (gren om Z = : i statusregistret, P)

vilket lägger till en -7 till den aktuella programräknaren och startar exekveringen på den nya programräknarens adress. Operanden är ett tvåkomplementnummer.

Absolut indexadressering
Med absolut indexadressering läggs innehållet i X- eller Y-registret till den givna absoluta adressen (var som helst från $0000 till $FFFF, d.v.s. från 010 till 6553610) för att få den verkliga adressen. Denna givna absoluta adress kallas basadressen. Om X-registret används är monteringsinstruktionen ungefär så här:

LDA $C453,X

Om Y-registret används skulle det se ut så här:

LDA $C453,Y

Värdet för X- eller Y-registret kallas räkne- eller indexvärde och det kan vara allt från $00 (010) till $FF (25010). Det kallas inte offset.

De absoluta indexadresseringsinstruktionerna är: ADC, AND, ASL (endast X), BIT (med ackumulator och minne, endast med X), CMP, DEC (endast minne och X), EOR, INC (endast minne och X), LDA , LDX, LDY, LSR (endast X), ORA, ROL (endast X), ROR (endast X), SBC, STA, STZ (endast X).

Absolut indirekt adressering
Detta används endast med hoppinstruktionen. Med detta har den givna absoluta adressen en pekadress. Pekaradressen består av två byte. Tvåbytepekaren pekar på (är adressen till) destinationsbytevärdet i minnet. Så instruktionen för assemblerspråk är som följer:

JMP ($3456)

Med parenteser och $13 i $3456-adress medan $EB är i $3457 (= $3456 + 1)-adress, är destinationsadressen $13EB och $13EB är pekaren. Absoluta $3456 står inom parentes i instruktionen.

9) a) Skriv ett 6502 maskinspråksprogram för att sätta 'Jag älskar dig!' sträng av ASCII-koder i minnet, med början från $0300-adressen med strängens längd. Programmet bör börja på $0200-adressen. Få varje karaktär från ackumulatorn, förutsatt att de skickas dit en efter en av någon subrutin. Sätt också ihop programmet för hand. (Om du behöver känna till ASCII-koderna för 'Jag älskar dig!', här är de: 'I':4916, space: 2016, 'l': 6C16, 'o':6F16, 'v':7616, ' e':65, 'y':7916, 'u':7516 och '!':2116. Observera: varje kod upptar 1 byte).

b) Skriv ett 6502 maskinspråksprogram för att sätta 'Jag älskar dig!' sträng av ASCII-koder i minnet, med början från $0300-adressen utan längden på strängen men slutar på 0016. Programmet bör börja på $0200-adressen. Få varje karaktär från ackumulatorn, förutsatt att de skickas dit en efter en av någon subrutin. Sätt också ihop programmet för hand.

Lösning:

a) Strategi: Det finns 12 byte för strängen: 1 byte för stränglängden och 11 byte för strängen. Så det måste finnas 12 iterationer (slingor) som räknas från 0. Det vill säga: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11. Det är 12 tal.

Heltalet 0 sätts i X-registret och talet 1110 = 1210 – 110 = B16 = $0B sätts på en adressplats i minnet, säg adress $0250. För varje iteration inkrementeras värdet i X-registret, och resultatet jämförs med $0B i $0250-adressplatsen. Precis efter att värdet i X är lika med värdet på $0B, stoppas iterationen. Vid denna tidpunkt upptar längden (antal byte) på strängen och strängen literal adressplatserna $0300 till $030B (inklusive). För att öka minnesadresserna från $0300 används Y-registret. Koden är:

LDA #$0B
DE ÄR 0250 $
LDX #$00
LDY#$00
STA $0300 ; längden 11 sätts in i A av någon subrutin och går till $0300
slinga INX
DÄR
CPY $0250
BEQ loop

b) Strategi: Det finns 12 byte för strängen: 1 byte för $00 Null terminator och 11 byte för strängen literal. Så det måste finnas 12 iterationer (slingor) som räknas från 0. Det vill säga: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11. Det är 12 tal.

Heltalet 0 sätts i X-registret och talet 1110 = 1210 – 110 = B16 = $0B sätts på en adressplats i minnet, säg adress $0250. För varje iteration inkrementeras värdet i X-registret, och resultatet jämförs med $0B i $0250-adressplatsen. Precis efter att värdet i X är lika med värdet på $0B, stoppas iterationen. Vid denna tidpunkt upptar antalet byte av strängen literal plus tecknet noll adressplatserna $0300 till $030B (inklusive). För att öka minnesadresserna från $0300 används Y-registret. Koden är:

LDA #$0B
DE ÄR 0250 $
LDX #$00
LDY#$00
STA $0300 ; 'I' sätts in i A av någon subrutin och går till $0300
slinga INX
DÄR
CPY $0250
BEQ loop