Wielobajtowe NOP-y
From Atariki
Wersja z dnia 21:47, 27 gru 2007 Xxl (Dyskusja | wkład) ← Previous diff |
Wersja z dnia 22:00, 27 gru 2007 KMK (Dyskusja | wkład) (uzupełnienia) Next diff → |
||
Linia 1: | Linia 1: | ||
Na stronie znajdują się metody pozwalające skrócić kod, często kosztem szybkości działania programu. | Na stronie znajdują się metody pozwalające skrócić kod, często kosztem szybkości działania programu. | ||
+ | == Użycie rozkazu BIT do zamaskowania innego rozkazu == | ||
- | '''Wartość w rejestrze A,X,Y zależy od parametru.''' | + | Rozkaz ''BIT abs'' (trzybajtowy: $2C ll hh) nie modyfikuje zawartości rejestrów (z wyjątkiem rejestru statusu 6502), więc może być użyty jako legalny, trzybajtowy NOP do zamaskowania dowolnego rozkazu dwubajtowego. Na ogół maskowane są w ten sposób rozkazy ładujące ośmiobitowe stałe do rejestrów. Technikę tę stosuje się na ogół w podprogramach, w których kod główny spełnia różne funkcje w zależności od stałego parametry przekazanego w akumulatorze, a punkty wejścia wywoływane są za pośrednictwem jakiejś tablicy adresów. Zamiast: |
- | przykład: | + | <pre> |
+ | E0 LDA #$00 | ||
+ | BEQ EXEC | ||
+ | E1 LDA #$01 | ||
+ | BNE EXEC | ||
+ | EFF LDA #$FF | ||
+ | EXEC ... | ||
+ | </pre> | ||
+ | |||
+ | piszemy: | ||
+ | |||
+ | <pre> | ||
+ | E0 LDA #$00 | ||
+ | .BYTE $2C | ||
+ | E1 LDA #$01 | ||
+ | .BYTE $2C | ||
+ | EFF LDA #$FF | ||
+ | EXEC ... | ||
+ | </pre> | ||
+ | |||
+ | Dzięki pozbyciu się skoków w tym przykładzie zaoszczędzono dwa bajty. Z tego prostego triku nagminnie korzysta kod [[SpartaDOS X]]. | ||
+ | |||
+ | Inne zastosowanie to załadowanie rejestru stałą w zależności od zmiennego parametru (gdy nie opłaca się zastosowanie tabeli). Przykład w pseudokodzie: ''IF zmienna=dana THEN A=dana1 ELSE A=dana2'' - badane mogą być inne relacje zmienna - dana. | ||
+ | |||
+ | Zamiast: | ||
<pre> | <pre> | ||
- | LDA zmienna | + | LDA zmienna |
- | CMP dana | + | CMP dana |
- | BNE _1 | + | BNE _1 |
- | LDA #dana1 | + | LDA #dana1 |
- | BNE _2 ; BEQ | + | BNE _2 ; BEQ |
- | _1 LDA #dana2 | + | _1 LDA #dana2 |
- | _2 ... | + | _2 ... |
</pre> | </pre> | ||
- | można zapisać również tak: | + | można zapisać tak: |
<pre> | <pre> | ||
- | LDA zmienna | + | LDA zmienna |
- | CMP dana | + | CMP dana |
- | BNE _1+1 | + | BNE _1+1 |
- | LDA #dana1 | + | LDA #dana1 |
- | _1 BIT $xxA9 ; $xx - dana2, $A9 kod rozkazu LDA | + | _1 BIT $xxA9 ; $xx - dana2, $A9 kod rozkazu LDA |
</pre> | </pre> | ||
[[Kategoria:Niezbędnik kodera]] | [[Kategoria:Niezbędnik kodera]] |
Wersja z dnia 22:00, 27 gru 2007
Na stronie znajdują się metody pozwalające skrócić kod, często kosztem szybkości działania programu.
Użycie rozkazu BIT do zamaskowania innego rozkazu
Rozkaz BIT abs (trzybajtowy: $2C ll hh) nie modyfikuje zawartości rejestrów (z wyjątkiem rejestru statusu 6502), więc może być użyty jako legalny, trzybajtowy NOP do zamaskowania dowolnego rozkazu dwubajtowego. Na ogół maskowane są w ten sposób rozkazy ładujące ośmiobitowe stałe do rejestrów. Technikę tę stosuje się na ogół w podprogramach, w których kod główny spełnia różne funkcje w zależności od stałego parametry przekazanego w akumulatorze, a punkty wejścia wywoływane są za pośrednictwem jakiejś tablicy adresów. Zamiast:
E0 LDA #$00 BEQ EXEC E1 LDA #$01 BNE EXEC EFF LDA #$FF EXEC ...
piszemy:
E0 LDA #$00 .BYTE $2C E1 LDA #$01 .BYTE $2C EFF LDA #$FF EXEC ...
Dzięki pozbyciu się skoków w tym przykładzie zaoszczędzono dwa bajty. Z tego prostego triku nagminnie korzysta kod SpartaDOS X.
Inne zastosowanie to załadowanie rejestru stałą w zależności od zmiennego parametru (gdy nie opłaca się zastosowanie tabeli). Przykład w pseudokodzie: IF zmienna=dana THEN A=dana1 ELSE A=dana2 - badane mogą być inne relacje zmienna - dana.
Zamiast:
LDA zmienna CMP dana BNE _1 LDA #dana1 BNE _2 ; BEQ _1 LDA #dana2 _2 ...
można zapisać tak:
LDA zmienna CMP dana BNE _1+1 LDA #dana1 _1 BIT $xxA9 ; $xx - dana2, $A9 kod rozkazu LDA