Lang: Nyelv: HU EN

P1516/p2223 assembler: p2as

A p2223 CPU-hoz kifejlesztett p2as assembler program alkalmas a processzoron futtatható assembly nyelvű programok lefordítására és a futtatható gépi kódú program létrehozására. Az assembler két menetben fordít és közvetlenül a futtatható kódot készíti el. Mivel nem generál átmeneti áthelyezhető (object) kódot, így nincs szükség szerkesztő (linker) programra.

Az assembler egyaránt képes a CPU 1-es verziójára (p1516), vagy a 2-es verziójára (p2223) készült programot lefordítani, a forrásban használható feltételek, utasítások a választott processzortól (assembly nyelv) függenek. A processzor kiválasztására szolgáló direktívát a forrás fájl elején kell elhelyezni. Ha nem alkalmazzuk, akkor a fordító alapértelmezés szerint a p1516 nyelvet használja.

A program parancssorban futtatható, a következő módon:

php p2as.php [-o kimenet] [-l] [-c] [-k] forrás_file...

A generált kimeneti fájl neve alapértelmezés szerint az elsőként megadott assembly forrás fájl nevével egyezik (a kiterjesztés .p2h-ra cserélésével), vagy megadható a -o kapcsoló paramétereként.

A -l kapcsolóval (list file creation) kérhetjük, hogy a program készítsen lista fájlt, amely a lefordított kódról tartalmaz részletes információkat. A fájl neve az első assembly forrás fájl nevével egyező lesz, .lst kiterjesztéssel.

A -c kapcsoló (compile only) használata esetén a fordító nem ad hibajelzést ha olyan szimbólumot használunk, amely nincs definiálva. Az ilyen módon lefordított kimeneti fájl nem alkalmas a program futtatására, mert az még félkész. Ez megfelel az egyéb fejlesztő rendszerekben használatos un. object fájl típusnak. Ezek a fájlok további fordításokban forrás fájlként adhatók meg, a tartalmuk bekerül a lefordított programba. A kimeneti fájlt ebben az esetben ajánlott .p2o kiterjesztéssel ellátni. Több forrás, vagy object fájl -c kapcsolóval való  lefordításával könyvtár fájlt készíthetünk, ezeket a fájlokat javasolt .p2l kiterjesztéssel elnevezni.

A -k kapcsoló (keep segments) használata esetén a fordító nem távolítja el azoknak a szegmenseknek a tartalmát, amelyekre nincsenek hivatkozások, így minden szegmens tartalma bekerül a kimeneti fájlba. Ennek a kapcsolónak csak akkor van hatása, ha a -c kapcsolót nem használtuk.

A program további paraméterei az assembly forrás fájlok, illetve object, vagy könyvtár fájlok nevei lehetnek, ezekből legalább egyet kötelező megadni. A megadott fájlok tartalmát a program összefűzi, és egy programként fordítja le. Ezért, ha a forrás több fájlban szétbontva található, azonos globális címkék nem fordulhatnak elő többször a fájlokban.

Assembly nyelv

A forrás fájlok más assembler-eknél megszokott szintaxisúak lehetnek. Az utasításokat egy sorba írva kell a fájban elhelyezni, a sorok a következő mezőket tartalmazhatják:

[címke:[:]] [feltétel] utasítás paraméterek [;megjegyzés]

A címke: (a szó végén lévő kettőspont jelöli), egy névvel (label) látja el azt a memória helyet, amelyre az utasítás kódszava kerül. Ugrásoknál és szubrutin hívásoknál használható a cím megadására. A címke a sorban egyedül is állhat, ekkor a forrásban ezután következő első utasítás helyét fogja jelölni.

Ha a címke neve után egynél több kettőspontot teszünk, akkor a címke globális lesz, akkor is, ha egy szegmensen belül hoztuk létre. Az így létrehozott szimbólumokat nem kell a .global direktívával exportálni.

Az utasítások feltétellel is elláthatók, ha valódi, CPU utasításokról van szó. Ha a feltételt nem adjuk meg, akkor AL (always) feltételt használja a program, amely a feltétel nélküli végrehajtást jelenti. Ugyanazt a feltételt több névvel is használhatjuk, amivel a program olvashatósága növelhető. A használható elnevezések a fordításhoz választott processzor típustól függnek, részletes felsorolásukat a melléklet tartalmazza.

Az utasítás lehet konkrét CPU utasítás (a választott processzor típustól függően), illetve a fordítónak szóló ún. pszeudó utasítás, direktíva.

A paraméterek az utasítástól függenek, ha több paramétert adunk meg, akkor azokat vesszővel kell elválasztani egymástól. Regiszterek megadásánál az R betűt és a regiszter sorszámát használjuk, pl. R10. Adatok esetében használhatunk címkeként létrehozott szimbólumokat, vagy konstansokat. A konstansoknak számjeggyel kell kezdődniük. A 0-val kezdődő konstansokat a fordító 8-as számrendszerűnek tekinti, a 0b-vel kezdődőeket kettes számrendszerűnek (bináris), míg a 0x-el kezdődőeket 16-osnak (hexadecimális). ASCII kódok megadására használhatjuk a ’b’ formát (az ASCII kód betűje egyszeres idézőjelek között), ún. escape szekvenciát, illetve szóközt azonban ilyen esetben nem használhatunk. A szimbólumok nevében a kis- és nagybetűk különbözőnek számítanak.

Assembler direktívák

Bizonyos utasítások nem a processzor utasításainak a leírására szolgálnak, nem a fordító működését szabályozzák, vagy egyéb eredményük van. A direktívák nevében a kis- és nagybetűk azonosnak számítanak. Azok a direktívák amelyeknek a neve nem ponttal kezdődik, ponttal kezdődően is megadhatók, tehát pl a CPU direktíva .CPU formában is használható.

PROC|CPU P1|P2

A használt processzor, és ezáltal az assembly nyelv kiválasztására szolgáló direktíva. P1 paraméter esetén a fordító a forrás fájlt p1516 processzor assembly nyelveként értelmezi, P2 esetén pedig a p2223 nyelvet használja. Ez a beállítás csak a CPU utasításokra vonatkozik, a fordító által felismert direktívák azonosak. A direktíva paramétere kis- és nagybetűvel is írható.

ORG érték

Az ORG utasítás paramétere egy számérték, ez lesz a memória cím számláló értéke. Arra használható, hogy valamilyen tartalmat egy adott memória területen helyezzünk el.

org 0 ; 0-s címen elhelyezve call rutin vege: jmp vege org 50 ; a rutint az 50-es címre tesszük rutin: ldl0 r1,0 ; ....

szimbólum EQU|=|== érték

Ezzel az utasítással (amelyet EQU, vagy =, illetve == formában is írhatunk) egy szimbólumnak értéket adhatunk.

porta = 0xff00 ; a kimeneti port címe ldl r0,porta ; a cím betöltése ldh r0,porta ; az R0 regiszterbe

Ha a == szimbólumot használjuk, akkor a szimbólum globálisként jön létre, vagyis egyúttal exportálódik a szegmensen kívülre, így a .global direktívát már nem kell használni.

DS|.SPACE|.SKIP érték

Ez a direktíva hely lefoglalására használható, a tartalom megadása nélkül. Paraméterként a hely méretét kell megadni. Ha a memóriában le akarunk foglalni valahány rekeszt adat tárolására, ezzel a direktívával megadhatjuk, hány szó helyre van szükségünk. A direktíva paraméterének 0-nál nagyobb pozitív számnak kell lennie.

org 20 ; ettől a címtő kezdve adatok: ds 5 ; 5 szó helyet foglalunk le

DB,DW,DD érték...

Ezekkel a direktívákkal a paraméterként megadott értékeket tudjuk elhelyezni a memóriában. A DB az érték alsó 8 bitjét használja fel, a DW 16 bitet, míg a DD 32 bites adatokat használ. Egy direktívánál több paraméter is megadható vesszővel elválasztva, ezek a felsorolás sorrendjében kerülnek a memóriába. A paramétereknek konstansnak, vagy szimbólumnak kell lenniük. A szimbólumok az EQU, = direktívákkal, vagy címkeként hozhatók létre.

Ezeknél a direktíváknál használhatunk sztring konstanst is, amely ”kettős idézőjelek” között megadott szöveg. A szövegen belül használhatók a C nyelvben megszokott escape szekvenciák is. A fordító a sztring konstansokat mindig kiegészíti egy 0 értékű szóval. Ebben az esetben a direktívának nem lehet más paramétere.

start: ldl0 r1,0 ... org 10 adat1: db 123 ; 8 bites adat db 65,’z’,13 ; ASCII konstans dw 0x213 ; 16 bites adat dd -4321 ; negatív számok is megadhatók dd start ; vagy címkék is db ”Hello World!\n” ; sztring konstans

DP “sztring”

Sztring elhelyezése a memóriában, “pakolt” formátumban. Négy karakter kódja kerül egy memóriahelyre, little-endian sorrendben, tehát az első karakter az alsó helyen lévő 8 bites helyre kerül. Az utolsó szó fel nem használt bájtjai 0 értékűek lesznek, majd egy 0 értékű szó zárja le a sztringet.

s3: .dp "Hello World!\n" ... 6c6c6548 //C 00087 dd 0x6c6c6548 ; "lleH" 6f57206f //C 00088 dd 0x6f57206f ; "oW o" 21646c72 //C 00089 dd 0x21646c72 ; "!dlr" 0000000a //C 0008a dd 0x0000000a ; "\012" 00000000 //C 0008b dd 0

SECTION|SEG|SEGMENT név [NOLOAD|ABS]

Szegmens kezdetét definiáló direktíva. A szegmensek a szimbólumok láthatóságát a szegmensen belülre korlátozzák, így az egyes szegmensek ugyanazt a szimbólum nevet saját célra használhatják.

Az első paraméter a szegmens neve, ami után opcionális paraméterek következhetnek. A szegmensen belül létrehozott szimbólumok és címkék csak a szegmensen belül láthatóak. Ha a szegmensen kívül is használni szeretnénk egy szimbólumot, akkor azt a GLOBAL direktívával exportálni kell.

A szegmensben újra definiálhatunk globális szimbólumokat. Ezekből egy új példány jön létre, így az értékük a szegmensen belül más lesz, mint a globális területen.

ENDS

A szegmens végét jelző direktíva. Ez után a program globális területe folytatódik, így a globális szimbólumok válnak láthatóvá.

GLOBAL|EXPORT név

A szegmensen belül definiált szimbólum globális szimbólummá való konvertálását végző direktíva. Paramétere a szimbólum neve. Csak egy paraméter adható meg. Ha a szimbólum a globális területen már létezik, akkor hibaüzenetet kapunk.

.INCLUDE fájlnév

A paraméterként megadott fájl betöltése és fordítása. A fájl nevét nem kell idézőjelbe tenni. A betöltött fájl után az aktuális fájl fordítása folytatódik. A fájlt a program először abban a könyvtárban keresi, ahol az eredeti forrásfájl található. Ha ott nem található, akkor a rendszer fájljai között fogja keresni, ez lehet a felhasználó saját könyvtárának p12tool/include alkönyvtára, vagy a fejlesztőrendszer lib alkönyvtára.

REQ reg alias

Regiszter alternatív elnevezésének létrehozása. Az alternatív név a fordítás hátralévő részében használható.

Mellékletek

Feltételek

A CPU utasításokban használható feltételek a kiválasztott processzor típusától függnek (lásd CPU direktíva). Egyes feltételek több különféle névvel is használhatók.

Feltételek p1516 processzor esetén

Feltétel Használható nevek
S==0 S0
S==1 S1
C==0 C0
C==1 C1
Z==0 Z0, NZ
Z==1 Z1, Z
O==0 O0
O==1 O1

Feltételek p2223 processzor esetén

Feltétel Használható nevek
Z==0 NE, ZC, Z0, NZ, T
Z==1 EQ, ZS, Z1, Z, F
C==0 (u1<u2) CC, LO, C0, NC, ULT
C==1 (u1>=u2) CS, HS, C1, C, UGE
S==0 PL, SC, S0, NS
S==1 MI, SS, S1, S
O==0 VC, OC, V0, O0, NV, NO
O==1 VS, OS, V1, O1, V, O
C==1 && Z==0 (u1>u2) HI, UGT
C==0 || Z==1 (u1<=u2) LS, ULE
S==O (s1>=s2) GE, SGE
S!=O (s1<s2) LT, SLT
Z==0 && S==O (s1>s2) GT, SGT
Z==1 || S!=O (s1<=s2) LE, SLE

Processzor utasítások, p1516

Az utasításokat ismertető táblázatban a következő rövidítéseket használjuk:

A konstansokban a # jelet nem kell használni, elég a számértéket, vagy a szimbólum nevét megadni. A regiszterek közül az R13 helyett használhatjuk az SP, az R14 helyett az LR, míg az R15 helyett a PC elnevezéseket is.

Mnemonic Paraméterezési módok Utasítás
NOP Rd,Ra,Rb
Rda,Rb
Rd
-
No operation
LD Rd,Ra Load from memory
ST Rd,Ra Store to memory
MOV Rd,Ra Move register to register
LDL0 Rd,#16 Load zex(immediate) to low
LDL Rd,#16 Load low of immediate to low
LDH Rd,#H16 Load high of immediate to high
CALL #27 Call subroutine
ADD Rd,Ra,Rb
Rda,Rb
Add without carry
ADC Rd,Ra,Rb
Rda,Rb
Add with carry
SUB Rd,Ra,Rb
Rda,Rb
Subtract without borrow
SBB Rd,Ra,Rb
Rda,Rb
Subtract with borrow
INC Rd,Ra
Rda
Increment
DEC Rd,Ra
Rda
Decrement
AND Rd,Ra,Rb
Rda,Rb
Bitwise AND
OR Rd,Ra,Rb
Rda,Rb
Bitwise OR
XOR Ra,Ra,Rb
Rda,Rb
Bitwise XOR
SHL Rd,Ra
Rda
Shift left
SHR Rd,Ra
Rda
Shift right
ROL Rd,Ra
Rda
Rotate left
ROR Rd,Ra
Rda
Rotate right
MUL Rd,Ra,Rb
Rda,Rb
Multiply
CMP Rd,Ra,Rb
Rda,Rb
Compare
SHA Rd,Ra
Rda
Shift arithmetic right
SETC - Set carry
CLRC - Clear carry

A következő makrók egyes utasítások alternatív elnevezéseiként használhatók.

Makró név Paraméterezési módok Jelentése
JMP #16 LDL0 R15,#16
JZ #16 Z LDL0 R15,#16
JNZ #16 NZ LDL0 R15,#16
RET - MOV R15,R14
PUSH Rd ST Rd,R13
POP Rd LD Rd,R13

Processzor utasítások, p2223

Az utasításokat ismertető táblázatban a következő rövidítéseket használjuk:

A konstansokban a # jelet nem kell használni, elég a számértéket, vagy a szimbólum nevét megadni. A regiszterek közül az R13 helyett használhatjuk az SP, az R14 helyett az LR, míg az R15 helyett a PC elnevezéseket is. A speciális regiszterek azonosítására a következő elnevezések használhatók:

Mnemonic Paraméterezési módok Utasítás
MOV Rd,Rb Move register to register
SED Rd,Rb Sex to double
MVL Rd,#16 Load low of immediate to low
MVH Rd,#H16 Load high of immediate to high
MVZL Rd,#16 Load zex(immediate)
MVS Rd,#16 Load sex(immediate)
GETB Rd,Rb,#2
Rd,Rb,Ri
Get byte
GETBS Rd,Rb,#2
Rd,Rb,Ri
Get sign extended byte
GETBZ Rd,Rb,#2
Rd,Rb,Ri
Get zero extended byte
PUTB Rd,Rb,#2
Rd,Rb,Ri
Put byte
RDS Rd,Rs Read special register
WRS Rd,Rs Write special register
ADD Rd,Rn,Rb
Rd,Rb
Rd,#16
Add without carry
ADC Rd,Rn,Rb
Rd,Rb
Rd,#16
Add with carry
SUB Rd,Rn,Rb
Rd,Rb
Rd,#16
Subtract without borrow
SBB Rd,Rn,Rb
Rd,Rb
Rd,#16
Subtract with borrow
CMP Rd,Rn,Rb
Rd,Rb
Rd,#16
Compare
MUL Rd,Rn,Rb
Rd,Rb
Rd,#16
Multiply
PLUS Rd,Rb
Rd,#16
Add without carry (do not alter flags)
BTST Rd,Rb
Rd,#16
Bit test (AND) with write-back
TEST Rd,Rb
Rd,#16
Bit test (AND) without write-back
OR Rd,Rn,Rb
Rd,Rb
Rd,#16
Bitwise OR
XOR Rd,Rn,Rb
Rd,Rb
Rd,#16
Bitwise XOR
AND Rd,Rn,Rb
Rd,Rb
Rd,#16
Bitwise AND
ZEB Rd Zero extend byte
ZEW Rd Zero extend word
SEB Rd Sign extend byte
SEW Rd Sign extend word
NOT Rd Bitwise NOT
NEG Rd Sign change
ROR Rd,Rn
Rd
Rotate right
ROL Rd,Rn
Rd
Rotate left
SHL Rd,Rn
Rd
Shift left
SHR Rd,Rn
Rd
Shift right
SHA Rd,Rn
Rd
Shift arithmetic right
SZ Rd Sign, zero check
SEC - Set carry
CLC - Clear carry
GETF Rd Get flags
SETF Rd Set flags
CALL Rd,#20
#24
Call subroutine
CES Rd,#20
#24
Call subroutine with embedded string
ST Rd,Ra,Ri
Rd,Ra+,Ri
Rd,Ra-,Ri
Rd,+Ra,Ri
Rd,-Ra,Ri
Rd,Ra,#16
Rd,*Ra,#16
Rd,Ra
Rd,#16
#16,Rd
Store to memory
LD Rd,Ra,Ri
Rd,Ra+,Ri
Rd,Ra-,Ri
Rd,+Ra,Ri
Rd,-Ra,Ri
Rd,Ra,#16
Rd,*Ra,#16
Rd,Ra
Rd,#16
#16,Rd
Load from memory

A következő makrók egyes utasítások alternatív elnevezéseiként használhatók.

Makró név Paraméterezési módok Jelentése
NOP - MOV R0,R0
JMP #16 MVZL R15,#16
JZ #16 Z MVZL R15,#16
FALSE #16 Z MVZL R15,#16
JNZ #16 NZ MVZL R15,#16
TRUE #16 NZ MVZL R15,#16
JC #16 C MVZL R15,#16
JNC #16 NC MVZL R15,#16
JP Rb MOV R15,Rb
RET - MOV R15,R14
PUSH Rd ST Rd,*R13,0
POP Rd LD Rd,*R13,0
INC Rd ADD Rd,1
DEC Rd ADD Rd,-1
LDL0 Rd,#16 MVZL Rd,#16
LDL Rd,#16 MVL Rd,#16
LDH Rd,#16 MVH Rd,#16