Upgrade to Pro — share decks privately, control downloads, hide ads and more …

6502 Assembly

6502 Assembly

Introduksjon til 6502 assembly med https://itema-as.github.io/6502js/ (Norwegian).

Avatar for Torkild U. Resheim

Torkild U. Resheim

December 22, 2020

More Decks by Torkild U. Resheim

Other Decks in Programming

Transcript

  1. Hvorfor lære assembler? • Laveste leselige abstraksjonsnivå for dataprogrammer. •

    Forstå litt mer om hvordan dataprogrammer og maskiner virker • Du har planer om skrive en kompilator • Det er gøy!
  2. MOS Technology 6502 • Lansert av MOS Technology i 1975

    • 1-3 MHz, 8 μm prosess • 3510/3218 transistorer • 8 bit databuss, 16 bit adressebuss • Little endian • Brukt blant annet i ◦ Rockwell AIM-65, Apple I, Apple IIe ◦ Commodore PET, BBC Micro, Electron, VIC-20, Atari Lynx, The Terminator • Oppgradert versjon 6510 ble i hovedsak brukt i Commodore 64 • WDC 65C02 er en moderne versjon som kan klokkes opp til 14 MHz ($6,95 USD)
  3. Fra kode til maskinkode • Både høynivåspråk og assembler må

    kompileres • En operasjon i f.eks. C++ resulterer gjerne i en rekke operasjoner i assembler • Tilnærmet 1:1 forhold mellom assemblerkode og maskinkode • Bytecode er som maskinkode, men for en virtuell maskin som Java VM eller CLR 10101001 01100001 A9 61 LDA #$61 Assemblerkode Heksadesimal Maskinkode Mnemoic Opcode Operand
  4. Registrene Disse seks registrene viser tilstanden til prosessoren. Her er

    det spesielt viktig å holde rede på programtelleren, den viser hvor man er hen i programmet. A, X og Y registrene er som variabler. PC Program Counter Gjeldende adresse i programmet AC Accumulator En 8-bits verdi, brukes i de fleste operasjoner XR X Register En 8-bits verdi YR Y Register En 8-bits verdi SR Status Register Statusregisteret, hver bit signaliserer en tilstand SP Stack Pointer Stakkpekeren, viser hvor man er hen i stakken
  5. Oppgaver Klarer du dette? 1. Tegn 3 prikker på skjermen

    (farge > $0) ved hjelp av alle dataregistene (A, X og Y) 2. Tegn en prikk i en tilfeldig farge på skjermen Hint: • Begynnelsen på skjermen er adresse $0200 • En absolutt verdi skrives på formen #$32 • LDA legger en verdi i A-registeret • STA lagrer verdien i A-registeret til en adresse • Adresse $FE inneholder et tilfeldig tall mellom 0 og 255 ($00-FF) hver gang man henter ut en verdi. Verdien kan representere en farge. • Tilsvarende har vi LDX, STX og LDY og STY
  6. ; Oppgave 1 LDA #$0f; “immediate” adressering STA $0200 LDX

    #$08 STX $0201 LDY #$01 STY $0202 ; Oppgave 2 LDA $fe ; “zero page” adressering STA $0200 Løsningsforslag Se i debuggeren og legg merke til verdien på de tre forskjellige registrene etter at løsningen på oppgave 1 har kjørt. Hva med programtelleren? Hva gjør “Disassemble”-knappen? Address Hexdump Disassembly ------------------------------ $0600 a9 0f LDA #$0f $0602 8d 00 02 STA $0200 $0605 a2 08 LDX #$08 $0607 8e 01 02 STX $0201 $060a a0 01 LDY #$01 $060c 8c 02 02 STY $0202
  7. Stakken "I don't understand why cheerleaders won't talk to me.

    Maybe I don't throw five touchdowns against Newport High, but let's see one of those football morons program in assembly language!" — Chris Lipe.
  8. Stakken • Stakken en er datastruktur til mellomlagring av data

    • Dette er såkalt LIFO eller Last In First Out • Gjeldende posisjon i stakken kalles SP eller stakkpekeren • Når en subrutine kalles med JSR legges instruksjonen etter JSR på stakken • Når subrutinen er ferdig og RTS kalles hentes SP fra stakken og programmet fortsetter • PHA og PLA pusher og popper A-registeret til og fra stakken • PHP og PLP gjør det samme med status-registeret • Alle “branch”-operasjonene (BNE, BEQ, PLP, etc.) legger også adresser på stakken
  9. Oppgaver Klarer du dette? 1. Lag en subrutine som tegner

    en prikk på skjermen og så returnerer, hva ligger i stakken? 2. Legg en verdi i A-registeret så i stakken, bruk monitoren til å se hvilken vei stakken vokser Hint: • Stakken begynner på adresse $0100 • Legg A-registeret i stakken med PHA, hent ut verdien med PLA • Begynnelsen på skjermen er adresse $0200 • Man kan navngi en rutine med tegnprikk: • Man kan hoppe til en rutine med JSR tegnprikk • Man returnerer fra en subrutine med RTS
  10. Løsningsforslag • Hvorfor er det puttet inn BRK i oppgave

    1, hva gjør den? ; Oppgave 1 JSR tegnprikk BRK tegnprikk: LDX #$07 STX $0200 RTS ; Oppgave 2 LDA #$00 PHA LDA #$01 PHA LDA #$02 PHA
  11. Statusregister og forgrening “The C Programming Language: A new language

    which combines the flexibility of assembly language with the power of assembly language.” – Murphy’s Introduction to C
  12. Statusregisteret 7 N Negative Kopieres fra MSB ved en aritmetisk

    operasjon? 6 V Overflow Er satt hvis resultatet av en signed-integer operasjon ikke passer (-128 - 127) 5 - Ignored Ikke i bruk 4 B Break Skiller mellom hardware interrupt og BRK 3 D Decimal Aktiverer binært-kodede desimaler for noen aritmetiske instruksjoner 2 I Interrupt Er satt hvis alle interrupt (unntatt NMI) er deaktivert 1 Z Zero Er satt hvis resultatet av en instruksjon, f.eks. subtraksjon er 0 0 C Carry Aritmetisk låne eller mente
  13. Oppgaver Klarer du dette? 1. Last #$7F i A-register og

    legg til 1, sjekk overflow og negativ bit 2. Gjør det samme som over med #$80. Hva er forskjellen? 3. Last inn 0x10000000 i A-register, gjør en shift left. Hva viser carry og zero? 4. Lag en for-next-loop som teller fra 0 til 127 ved hjelp av X-register (bonus: tegn en pixel på posisjon X). 5. Lag en if-then-else som sjekker fortegn på A-register og tegner henholdsvis blå/rød pixel Hint: • Aktuelle operasjoner for oppgave 1 LDA, ADC • 0x10000000= #$80 • Shift left = ASL • Inkrementer X-register med INX • Lagre fargekode i A-register, STA • STA $0200,X • BPL, BMI
  14. ; Oppgave 1: LDA #$7f ADC #$01 ; Oppgave 2:

    LDA #$80 ADC #$01 ; Oppgave 3: LDA #$80 ASL A ; Oppgave 4: LDX #$00 loop: INX CPX #$7f BNE loop BRK Løsningsforslag ; Oppgave 5: LDA #$ff CMP #$00 BPL blue red: LDA #$02 STA $0200 BRK blue: LDA #$06 STA $0200 BRK
  15. Aritmetikk • Som de fleste CPU’er kan 6502 kun legge

    til og trekke fra • C-flagget (carry) brukes både ved addisjon og subtraksjon men har motsatt funksjon ved sistnevnte. • Nyttige instruksjoner: ADC (Add with Carry), CLC (Clear Carry), SBC (Subtract Memory from Accumulator with Borrow), SEC (Set Carry) • DEX, INX, DEY og DEX dekrementerer og inkrementerer henholdsvis X og Y-registrene. DEC og INC gjør tilsvarende for adresse eller verdi
  16. Oppgaver Klarer du dette? 1. Legg sammen 88 og 70,

    ta med en i mente 2. Trekk 70 fra 88, prøv både å låne og uten Hint: • CLD aktiverer binærmodus for aritmetikk • Ved subtraksjon: SEC setter låne til 0, CLC setter låne til 1 • Ved addisjon: SEC setter en i mente, CLC erner en i mente • LDA legger en verdi i A-registeret • ADC legger sammen en verdi med det som ligger i A-registeret • SBC (Subtract Memory from Accumulator with Borrow)
  17. Løsningsforslag ; Oppgave 1: CLD ; Aktiver binærmodus (88 +

    70 + 1 = 159) SEC ; Merk at mente er satt LDA #$58; 88 ADC #$46; 70 (C = 0, A = $9F = 159) ; Oppgave 2: CLD ; Aktiver binærmodus (88 - 70 = 18) SEC ; Merk at låne er ikke satt! LDA #$58; 88 SBC #$46; 70 (C = 1, A = $12 = 18) CLD ; Aktiver binærmodus (88 - 70 = 18) CLC ; Merk at låne er satt! LDA #$58; 88 SBC #$46; 70 (C = 1, A = $11 = 17)
  18. Oppgave: Fargebonanza Klarer du dette? 1. Tegn 256 forskjellig fargede

    punkter på skjermen. 2. Tegn 256 forskjellig fargede punkter på skjermen 256 ganger for å lage en slags animasjon. 3. Tegn den samme tilfeldige fargen i en hel linje. Ta en ny tilfeldig farge og gjenta til hele skjermen er fylt. (vanskelig) Hint: • Adresse $FE inneholder et tilfeldig tall mellom 0 og 255 ($00-FF) hver gang man henter ut en verdi. Verdien kan representere en farge. • Begynnelsen på skjermen er adresse $0200 • Bruk X og Y registrene til å holde tellinga • INX øker verdien i X-registeret med 1 • CPX sammenligner en verdi med X-registeret • LDA legger en verdi i A-registeret • STA lagrer verdien i A-registeret til en adresse • Man kan navngi en adresse med start: • Man kan hoppe til en adresse med BNE start
  19. LDX #$0 ; Start i øverste venstre hjørne loop: ;

    Definer starten på sløyfa LDA $FE ; Hent en tilfeldig verdi STA $0200,X ; Lagre denne verdien på skjermen, offset X INX ; Inkrementer verdien i X-registeret med 1 CPX #$FF ; Sammenlign verdien i X med 255 BNE loop ; Hvis ikke lik 255 hopp til loop Løsning: Fargebonanza 1
  20. LDY #$0 ; Legg 0 i Y-registeret LDX #$0 ;

    Start i øverste venstre hjørne start: ; Definer starten på den ytre sløyfa loop: ; Definer starten på den indre sløyfa LDA $FE ; Hent en tilfeldig verdi STA $0200,X ; Lagre denne verdien på skjermen, offset X INX ; Inkrementer verdien i X-registeret med 1 CPX #$FF ; Sammenlign verdien i X med 255 BNE loop ; Hvis ikke lik 255 gå til loop CPY #$FF BNE start Løsning: Fargebonanza 2