Dezvoltat limbajul adaptiv PARADISE al sistemului de programare dialog DSSP Moskovsky Universitate de stat Facultatea de Matematică Computațională și Cibernetică N.P. Brussentsov, V. B. Zaharov, I. A. Rudnev, S. A. Sidorov, N. A. Chanyshev Moscova, 1987
Descrierea generală a limbajului PARADIS
Scopul și scopul dezvoltării limbajului
PARADISE (Developable Adaptive Language) este limbajul de bază al sistemului de dialog de programare structurată DSPP. De bază înseamnă că stă la baza tuturor construcțiilor ulterioare realizate în DSSP prin dezvoltarea (extinderea, întărirea) limbajului de bază și, poate, adaptarea mijloacelor lingvistice create în acest fel la o aplicație specifică. Spre deosebire de așa-numitele limbaje de nivel înalt, PARADIS nu oferă tipuri de date și operațiuni gata făcute, ci doar elemente și primitive pentru a defini eficient tipurile necesare. De exemplu, formatele de date originale sunt octeți de 8 biți, cuvinte de 16 biți și cuvinte lungi de 32 de biți, interpretate în funcție de operațiunile efectuate asupra acestora ca numere întregi, vectori booleeni, coduri de litere, booleeni, indicatori de date și proceduri. În acest caz, este posibil, pe de o parte, să se manipuleze biți individuali de octeți și cuvinte și, pe de altă parte, să se formeze unități de date compuse (cuvinte de lungimi multiple, vectori, matrice, șiruri de text etc.), stabilindu-le pentru ele una sau alta interpretare introducerea unor operatii adecvate. Deci, pot fi introduse numere reale cu lungimea și intervalul de valori necesare, numere complexe și alte obiecte, iar versiunea limbajului orientată către o anumită aplicație va include obiecte și mijloace inerente acestei aplicații și nu va include nimic care nu include aplicați-i - limbajul va fi adaptat (adaptat) aplicației. Dezvoltarea DSPP a avut ca scop crearea unui sistem disponibil pe scară largă și remediu eficient programarea microcalculatoarelor, de ex. calculatoare bazate pe microprocesoare. O caracteristică esențială a arhitecturii microprocesoarelor este caracterul elementar al tipurilor de date și al operațiilor, ceea ce înseamnă, pe de o parte, universalitatea și, pe de altă parte, laboriozitatea programării. Datorită versatilității lor, microprocesoarele și microcalculatoarele create pe baza lor au posibilități nelimitate de aplicare. Cu toate acestea, implementarea practică a acestor capabilități se bazează în primul rând pe laboriozitatea dezvoltării programelor de aplicație necesare. În plus, programele de aplicație satisfăcătoare pot fi create doar cu o cunoaștere profundă și subtilă a specificului aplicațiilor respective, i.e. ar trebui să fie dezvoltate nu doar de programatori, ci și de specialiști cu înaltă calificare într-un domeniu sau altul. Prin urmare, sistemul de programare nu numai că ar trebui să mărească foarte mult productivitatea muncii programatorului, ci și să fie atât de simplu încât să poată fi stăpânit și utilizat eficient de programatori neprofesioniști.
O soluție radicală la această problemă ar părea a fi o simplificare semnificativă a arhitecturii computerului. Dar, din păcate, arhitectura microcalculatoarelor se dezvoltă într-o direcție diametral opusă - pe calea creșterii complexității și rafinamentului, astfel încât nu este ușor pentru un programator profesionist să stăpânească perfect limbajul unui asamblator de microcalculatoare astăzi. Limbajele de programare de sisteme precum C sau PL / M au redus, într-o anumită măsură (deși departe de a fi suficiente), complexitatea dezvoltării programelor, dar cu greu pot fi recomandate persoanelor care nu au experiență în domeniul programarii. Un limbaj disponibil pe scară largă ar trebui, desigur, să fie mai simplu și mai natural, ar trebui să se bazeze, pe cât posibil, pe idei obișnuite, familiare despre esența și tehnica programării.
Pe lângă disponibilitatea și reducerea semnificativă a complexității dezvoltării programelor în comparație cu programarea în limbaj de asamblare, DSSP a necesitat versatilitatea limbajului, la fel ca cea a limbajului de asamblare, eficiență ridicată a mașinii (adică compactitatea și viteza cod), fiabilitatea testabilității programelor create și mentenabilitatea și modificabilitatea acestora, precum și mobilitatea (portabilitatea) sistemului și a programelor dezvoltate în acesta la mașini cu arhitecturi diferite.
Programare procedurală
Programarea în limbajul PARADISE este destul de asemănătoare cu tipuri atât de răspândite de activitate umană, cum ar fi planificarea și organizarea acțiunilor, lucrărilor, proceselor interdependente sau construcția de obiecte materiale complexe - mașini, unități, structuri. Asemenea unui designer care își realizează ideea prin agregarea părților sale constitutive (blocuri, ansambluri, piese), programatorul sintetizează acțiunea complexă necesară din acțiunile simple oferite de limbaj. De asemenea, putem spune că programarea (proiectarea) este descompunerea (descompunerea) treptată a obiectului implementat în componente din ce în ce mai mici.
În limbajul PARADIS, principalul „construct” este o procedură - o acțiune numită. Limbajul se bazează pe un set limitat de cele mai simple procedee (primitive), reprezentate de propriile nume (desemnări). De exemplu: + înseamnă adăugare, NEG înseamnă schimbare semn, VCTR înseamnă creare vector. În special, există primitive: și; (virgulă și punct și virgulă), permițându-vă să introduceți o nouă procedură, de exemplu, cu numele P, definindu-l ca o secvență de proceduri P1, P2, ..., PN sub forma
: P P1 P2 ... PN;
Daca procedura P reprezinta actiunea pe care programul creat ar trebui sa o realizeze, constructia acestui program prin intermediul limbajului PARADISE se reduce la detalierea secventiala a procedurilor P1, P2, ..., PN. Aceasta înseamnă că fiecare dintre aceste proceduri trebuie să fie definită printr-o succesiune de proceduri mai mici, care sunt apoi definite prin secvențe de proceduri și mai mici, și așa mai departe, până când se obțin definiții constând doar din primitive.
Acest design al unui program, pornind de la o țintă dată și reducând treptat procedurile pe care le utilizează până la nucleul limbajului, este cunoscut sub numele de programare de sus în jos. Este modalitatea principală de obținere a programelor în limbajul PARADIS pentru rezolvarea unor probleme individuale, bine definite. Opusul este programarea de jos în sus - construirea unui sistem de proceduri treptat lărgite bazate pe mijloacele de bază ale limbajului, concentrate pe o anumită zonă problematică. În acest fel, se realizează dezvoltarea limbajului și adaptarea lui la o aplicație specifică.
În ambele cazuri, o structurare minuțioasă a programelor create este esențială: fiecare program și fiecare parte a unui program trebuie să fie formată dintr-un număr mic de părți separate, fiecare dintre ele îndeplinește o funcție specifică și permite verificarea autonomă. În ceea ce privește limbajul PARADISE, aceasta înseamnă, în special, că definițiile procedurilor ar trebui să fie scurte: secvența definitorie, de regulă, nu trebuie să conțină mai mult de 5-7 membri. Structurarea oferă claritate, verificabilitate și modificare a programului, reduce semnificativ complexitatea creării și întreținerii acestuia.
Exemplul de mai sus de definire a procedurii P este simplificat. De fapt, secvența definitorie poate conține ca membri nu doar denumirile de proceduri, ci și instrucțiuni (comenzi) formate din mai mult de un cuvânt. Un nume de procedură, atunci când este utilizat în afara combinației cu alte cuvinte, este o comandă pentru a executa procedura desemnată de acesta. Succesiunea numelor de proceduri dictează executarea acestor proceduri în ordinea numelor lor una după alta (în ordine liniară). Pentru a specifica alte secvențe de execuție, PARADISE oferă cuvinte speciale (prefixe) care prescriu execuția procedurilor numite în combinație cu acestea, în funcție de condiția specificată, precum și execuția repetată (ciclică) a procedurii.
De exemplu, o secvență liniară P0 P1 face ca procedura P0 să fie executată și apoi procedura P1 să fie executată. Dacă procedura P1 trebuie efectuată nu întotdeauna, ci mai degrabă dacă se prevede ca în urma executării P0 să se obțină un număr pozitiv, atunci în locul lui P1 se scrie comanda de execuție conform condiției: IF + P1, adică. în loc de P0 P1 va fi P0 IF + P1. PARADISE include un set de condiții de prefix care vă permit să exprimați în mod eficient execuția condiționată, precum și o alegere a două, trei sau mai multe proceduri.
Executarea multiplă a procedurii este specificată folosind prefixul RP. Deci, comanda RP P apelează din nou și din nou execuția procedurii P până când sunt create condițiile în care este declanșat EX conținut în corpul acestei proceduri - ieșire din buclă, după care se execută următoarea comandă în ordine liniară . Condiția de ieșire din buclă poate fi, de exemplu, egalitatea cu zero a unei variabile X, care este exprimată ca:
Se spune că o procedură al cărei nume apare în definiția altei proceduri este imbricată în ea. O procedură imbricată, dacă nu este o primitivă, poate conține la rândul său proceduri imbricate, de exemplu. cuibărirea poate fi multiplă. În plus, regulile limbajului PARADISE nu interzic includerea în definiția unei proceduri a numelui propriu sau a denumirii unei proceduri care conține acest nume, adică. PARADIS permite recursiunea.
Procedura executată în mod repetat poate fi imbricată și în procedura executată în mod repetat. În acest caz, buclele sunt imbricate. PARADISE permite imbricarea mai multor bucle.
Secvență liniară de comenzi, imbricare, imbricare condiționată și ciclică a procedurilor - aceasta epuizează posibilitățile de construire a programelor în limbajul PARADISE. Purețea, omogenitatea și naturalețea acestor mijloace este o garanție a ușurinței în stăpânirea și utilizarea limbajului. În același timp, este un limbaj de programare structurat riguros care oferă o reducere semnificativă a intensității muncii de dezvoltare și a fiabilității programului.
Proceduri și date
Tot ceea ce s-a spus până acum este o caracteristică a limbajului PARADIS ca mijloc de a prescrie acțiuni, de a construi acțiuni arbitrare dintr-un set finit de operații primitive. Cealaltă parte a limbajului este alcătuită din mijloacele de reprezentare a obiectelor peste care acţiuni, - mijloace prezentarea si organizarea datelor.
Cu totul element simplu datele sunt un element din două cifre - un bit. Toate celelalte formate și tipuri de date sunt construite din biți. În limbajul PARADISE, biți de 8 biți, cuvânt de 16 biți și cuvânt lung de 32 de biți sunt acceptate ca formate de bază. În funcție de operațiile efectuate asupra lor, octeții, cuvintele și cuvintele lungi admit multe interpretări, adică. poate servi drept bază pentru tipuri diferite date. Ele sunt, de asemenea, punctul de plecare pentru formarea de formate și tipuri compozite.
De fapt PARADISE nu conține nici tipuri de date simple, nici compuse - există doar formate de bază (octet, cuvânt, cuvânt lung) și mijloace pentru a construi formate compuse din acestea: vectori și tablouri multidimensionale. În acest caz, aceiași octeți (cuvinte, cuvinte lungi), în funcție de operațiunile efectuate asupra lor, sunt interpretați ca vectori de biți, sau ca numere întregi binare cu și fără semn, sau ca litere ale alfabetului de intrare/ieșire etc. . Tipurile de date și constrângerile și verificările asociate acestora pot fi introduse în extensiile de limbaj orientate spre probleme.
În limbajul de bază, declararea numelor de date îndeplinește doar funcția de a oferi acces la date după nume: numele este asociat cu numărul de celule de memorie cerut de declarație și mecanismul de accesare a acestora. Operațiunile de testare și transformare nu sunt aplicate direct datelor cu nume. Aceste operații sunt definite pe stiva de operanzi, care este o secvență de cuvinte lungi de 32 de biți (elemente de stivă) care este schimbată dinamic prin adăugarea (împingerea) elementelor noi la capătul său, precum și prin eliminarea elementelor de la același capăt (ieșind din teancul). Elementele sunt retrase în ordinea inversă celei în care au fost trimise: ceea ce a fost trimis de ultimul este retras primul. Datele care urmează să fie testate sau convertite sunt împinse în stivă, unde sunt efectuate operațiunile prescrise pe acesta, după care rezultatele procesării pot fi scoase din stivă.
De exemplu, dacă există o variabilă X declarată ca un cuvânt lung de 32 de biți, atunci doar două operații pot fi efectuate direct asupra acesteia:
1) împingerea valorii acesteia pe stivă, care apare automat de fiecare dată când este menționat numele X,
2) atribuirea acestuia de către comandă! Valoarea X a ultimului element (de sus) a ieșit din stivă.
Dacă, de exemplu, doriți să dublați valoarea lui X adăugându-l la sine, atunci puteți face acest lucru executând următoarele comenzi una după alta:
Două copii ale valorii X vor fi împinse pe stivă, apoi comanda + le va afișa, adăuga și împinge cantitatea rezultată pe stivă, după care comanda! X va elimina această sumă și va atribui valoarea acesteia variabilei X.
Notarea obișnuită pentru limbaje de nivel înalt a exemplului dat în forma X: = X + X este mai familiară programatorului, dar nu este o reflectare directă a secvenței de instrucțiuni executate de procesor, ci este o un fel de formulă matematică. Acest lucru este convenabil la programarea sarcinilor de calcul; cu toate acestea, în limbajul de bază, o corespondență neechivocă cu comenzile executate pare să fie mai importantă, deoarece programul poate fi verificat prin comandă direct în limbajul de programare și nu este nevoie să cunoașteți un limbaj. în afară de limbajul procesorului.
Dar un avantaj deosebit de valoros al procesării datelor stivuite este că rutinele de testare și transformare pot fi definite și implementate independent de datele la care sunt aplicate. Operațiile de testare și transformare sunt formulate nu cu privire la identificatorii de date (sau nume de constante și variabile, parametri formali), ci cu privire la elementele stivei, cărora trebuie să li se atribuie valorile operanzilor până la momentul operației. se efectuează. De exemplu, operația de adunare a două numere, efectuată prin comanda + (adăugare), constă în preluarea celor două elemente de sus (top și sub) din stivă ca sume, calcularea sumei lor și împingerea acesteia pe stivă. Pentru a adăuga două numere, trebuie să le împingeți valorile pe stivă și să executați comanda +, rezultatul va fi în partea de sus a stivei.
O procedură de testare-transformare cu un număr arbitrar de parametri de intrare și de ieșire poate fi definită în acest fel pur și simplu ca o acțiune numită (fără o listă de parametri) efectuată pe stiva care conține valorile argumentului în ordinea prescrisă și după execuție - valorile rezultatelor. Pentru a aplica o astfel de procedură unui anumit set de date specifice, este necesar să introduceți aceste date în secvența corespunzătoare în stivă. După ce le-a consumat, procedura își va lăsa rezultatele pe stivă (de asemenea, aranjate într-o anumită secvență).
Cu alte cuvinte, denumirile de proceduri în limbajul PARADISE sunt folosite în același mod ca semnele operațiilor și sunt în esență simboluri ale operațiilor cu un număr arbitrar de operanzi. În conformitate cu principiul de funcționare a stivei, operațiunile sunt scrise sub formă de postfix, i.e. numele operațiunii este plasat după listarea numelor sau valorilor operanzilor acesteia. De exemplu, dacă notați operația de obținere a sumei a trei numere prin simbolul ++, atunci suma numerelor A, 5 și B va fi exprimată după cum urmează:
Ar fi posibil să se stabilească reguli formale ale unui limbaj postfix și să fie ghidat de acestea atunci când scrieți programe, dar este mai ușor și mai sigur pentru o persoană să se ocupe nu de reguli, ci de un model de procesor de stivă, de exemplu. cu modelul maşinii pentru care sunt create programele şi care le va executa. În cazul limbajului PARADISE, o astfel de mașină este procesorul DSPP - un set de hardware și programe care implementează acțiuni prescrise în acest limbaj.
procesor DSP
Din punct de vedere fizic, procesorul DSPP poate fi implementat sub forma unui microprocesor de arhitectură simplă și eficient programabilă care ar rezolva problema echipamentelor software ale microcalculatoarelor. cel mai bun mod... Dar un astfel de microprocesor nu a fost încă creat și arhitectura sa trebuie emulată pe microcalculatoarele existente pentru a le îmbunătăți programabilitatea. Desigur, emularea este costisitoare - necesită memorie și timp de mașină pentru a o implementa, dar în cazul emulării unui procesor PRSP, aceste costuri sunt relativ mici.
Din punctul de vedere al programatorului, caracteristica unui procesor este arhitectura acestuia, i.e. informații despre ce este un anumit procesor ca instrument de prelucrare a datelor, care sunt posibilitățile de prezentare a datelor la intrare și în interiorul procesorului, ce operațiuni de testare și conversie a datelor sunt disponibile, cum este organizată memoria proprie a procesorului, precum și accesul la memoria principală și externă, care sunt controalele cursului programului, interacțiunea cu Mediul extern, răspuns la evenimente excepționale etc. Stăpânirea arhitecturii înseamnă conditie necesara programare semnificativă (informală), care reduce semnificativ numărul de erori și crește fiabilitatea programelor.
Legătura centrală a procesorului DSPP este stiva de operanzi menționată mai sus. În stiva în sine, procesarea este efectuată, iar datele sunt de obicei transferate prin stivă, de regulă. Comenzile individuale și secvențele scurte de comenzi peste stivă pot fi executate prin alimentarea lor la intrarea procesorului direct de la tastatura terminalului. În acest caz, procesorul DSPP simulează funcționarea unui calculator postfix. Numerele și codurile mnemonice ale operațiilor introduse de la tastatură sunt separate prin spații. Textul introdus este afișat ca șir pe ecranul terminalului. Semnalul de sfârșit de intrare și comanda către procesor „Execută prescripția introdusă” este apăsarea tastei
De exemplu, pentru a calcula expresia (2-5) * 3 și a afișa rezultatul, introduceți:
2 5 - 3 * .
După apăsarea tastei
* 2 5 - 3 * . -90
Un asterisc la începutul unei linii este emis de procesor ca un semnal că așteaptă intrarea.
În exemplul considerat, procesorul a perceput și procesat numerele de intrare ca zecimale întregi. De fapt, la introducere, aceste numere au fost convertite în complementul binar, iar la ieșire, au fost convertite înapoi în sistemul zecimal. Procesorul PRSP permite, de asemenea, moduri I/O binar, octal și hexazecimal. Pentru a trece la modul dorit, trebuie executată una dintre comenzile B2, B8, B10, B16.
Apăsarea tastelor face ca intrarea procesorului să furnizeze coduri reprezentând literele indicate pe aceste taste (litere, cifre, semne de punctuație, simboluri ale operațiilor). Secvența de caractere de intrare formează un șir de intrare - un lanț de octeți care conține codurile caracterelor, câte un octet pe caracter. Lungimea maximă a unui șir de intrare este de 80 de caractere.
La procesarea șirului de intrare, procesorul izolează cuvintele din acesta - combinații de litere separate între ele prin spații și le interpretează. Dacă cuvântul în procesare este numele unei operații (procedură) sau al uneia date, cunoscute de procesor, atunci procesorul efectuează acțiuni care trebuie numite cu acest nume prin definiție. Dacă cuvântul nu este cunoscut de procesor, atunci acesta încearcă să-l interpreteze ca număr, ținând cont de modul I/O setat.
Numerele sunt recunoscute ca cuvinte formate din cifre admisibile într-un anumit sistem numeric și, probabil, care conțin un semn minus ca primă literă. În modul de intrare/ieșire hexazecimal, sunt valabile și literele latine A, B, C, D, E, F, împreună cu numerele. Numărul primit este convertit în codul de complement doi și împins în stiva de operanzi ca o lungime de 32 de biți. cuvânt. În acest caz, dacă valoarea numărului se află în afara intervalului de valori reprezentabile -2147483648: 2147483647, atunci este înlocuită cu o valoare comparabilă în modulul 2 ** 32 din acest interval.
În cazul în care cuvântul procesat nu este cunoscut de procesor și nu poate fi acceptat ca număr, procesorul afișează pe ecranul terminalului un mesaj: „Nu știu<обрабатываемое слово>„și așteaptă să fie introduse alte rețete.
Introducerea datelor sub formă de text liber (secvență de octeți-litere) se realizează sub formă de literale text, care sunt text cuprins între ghilimele duble, de exemplu: „Literal text”. Sosirea unui literal de text ca intrare în procesor face ca textul cuprins între ghilimele să fie scris în memoria principală ca un șir de litere-octeți. În acest caz, adresa primului octet și numărul de octeți (lungimea textului) sunt împinse în stivă. Un text literal precedat de un punct este interpretat de procesor ca o comandă pentru „trimite textul dintre ghilimele pe ecranul terminalului”. De exemplu, introducerea combinației de simboluri la intrarea procesorului „Fără memorie” va face ca mesajul: Fără memorie să apară pe ecran.
Codul unui caracter individual este împins în stivă ca octet cel mai puțin semnificativ al vârfului atunci când acest caracter ajunge la intrarea procesorului împreună cu semnul # care îi este trimis. De exemplu, combinația de caractere #L va trimite codul litera L pe stivă, combinația de # 5 caractere va trimite codul cu numărul 5. Comanda TOB pentru a trimite un octet către terminal afișează un caracter al cărui cod este conținut în octet din partea de sus a stivei.
Chiar și în modul de execuție directă a comenzilor, procesorul PRSP depășește cu mult capacitățile unui calculator convențional, punând la dispoziție utilizatorului, pe lângă operațiunile de prelucrare a datelor, mijloace de declarare a datelor denumite și de definire a procedurilor care pot fi apoi utilizate împreună cu operațiunile de bază. operațiuni. Numele datelor sunt declarate și procedurile sunt definite folosind comenzi speciale.
De exemplu, pentru a crea o variabilă de 16 biți numită, de exemplu, TEMP, tastați pe tastatură și introduceți-o la intrarea procesorului cu tasta
VAR TEMP
Puteți atribui unei variabile împreună cu declarația valoarea initiala de exemplu 0:
VAR TEMP 0! TEMP
Acum, sosirea numelui TEMP la intrarea procesorului va face ca valoarea curentă a acestei variabile să fie împinsă în stivă, iar atribuirea unei noi valori apărute din stivă la acesta poate fi efectuată prin comandă! TEMP.
O definiție de procedură este introdusă printr-o comandă: (colon) care conține numele procedurii care se definește și definește un lanț de comandă cu o literă; (punct și virgulă) ca caracter de sfârșit de definiție. Să demonstrăm definirea și utilizarea procedurilor prin exemplul de calcul al factorialului unui număr natural N prin formula
N! = N * (N-1) * (N-2) * ... * 2 * 1, adică Înmulțirea N-1.
Procedura FCT pentru a obține rezultatul dorit trebuie să înmulțească numărul dat N cu numere descrescătoare succesive, începând de la N-1 la 1, adică. doar de N-1 ori. În limbajul PARADISE, aceasta este programată prin executarea de t ori a procedurii P: DO P, unde P este numele procedurii, t este valoarea curentă a vârfului stivei, indicând de câte ori are nevoie procedura P. a fi executat.
Să presupunem că înainte de aplicarea procedurii FCT, numărul N este împins pe stivă și se află în partea de sus. Pentru a clarifica procedura, reprezentăm multiplicatorul modificabil al variabilei K:
Introducem definiția procedurii FCT sub forma:
FCT [N]! K K K 1- DO F. [N];
Comentariile dintre paranteze drepte reflectă starea curentă a stivei de operanzi. Echipă! K, cu care începe procedura definită, atribuie variabilei K valoarea numărului N luat din stivă. Apoi K este împins pe stivă de două ori, iar prin scăderea lui 1 din vârful stivei, numărul de execuții ale se formează procedeul repetat F egal cu N-1. Aceasta este urmată de comanda DO F, care prescrie o buclă, după care partea de sus a stivei va conține valoarea factorială necesară - N !. Echipă. (punct) tipărește o copie a acestei valori pe ecranul terminalului. Rămâne de definit procedura F, care modifică valoarea lui K scăzând 1 și înmulțește cu K rezultatul parțial al calculului lui R. conținut în stiva:
F [R] K 1-! K [R] K *;
Verificarea corectitudinii ambelor proceduri se realizează prin executarea definițiilor acestora pe rând și afișarea conținutului stivei de operanzi și a valorii variabilei K pe ecranul terminalului după fiecare comandă.La finalizarea procedurii FCT, partea de sus a stiva trebuie să conțină valoarea N !, iar valoarea variabilei K trebuie să fie egală cu 1.
Procedurile verificate și corectate (dacă au fost detectate erori în timpul procesului de verificare) sunt testate prin aplicarea acestora la valori individuale ale numărului N. Deoarece procedura F este imbricată în FCT, aceasta este testată automat în timpul ultimului proces de testare. Trebuie avut în vedere că valorile rezultatului nu trebuie să depășească numărul maxim pozitiv reprezentat în codul de complement printr-un cuvânt lung de 32 de biți: 2147483647, i.e. FCT dă rezultate corecte numai pentru N = 1, ..., 13.
Utilizarea FCT nu diferă de utilizarea instrucțiunilor proprii ale procesorului: pentru a obține rezultatul, trebuie să setați valoarea operandului și să introduceți numele procedurii:
5 FCT
7 FCT
Implementarea de mai sus a procedurii FCT a necesitat introducerea unei variabile auxiliare K, cu toate acestea, o procedură echivalentă din punct de vedere funcțional poate fi efectuată fără o variabilă auxiliară folosind operația C, care împinge o copie a vârfului său pe stivă și operațiile E2 și E3, care schimbă vârful cu al doilea și, respectiv, al treilea element al stivei. Definiția acestei proceduri este următoarea.
: FCTA [N] C 1- C DO FA D. ;
: FA C E3 * E2 1-;
Avantajul unei astfel de proceduri „pur stivă” este autonomia sa completă: la fel ca și operațiunile de bază de stivă ale procesorului, se realizează doar pe stiva de operanzi, fără a necesita nicio altă memorie și fără a provoca modificări în alte componente ale procesorului.
Denumirile procedurilor definite și datele declarate sunt introduse în dicționarul procesorului, care stabilește legătura acestor nume cu obiectele numite, adică cu corpurile de procedură aflate în memoria principală și cu elementele acestei memorie alocate pt. stocarea datelor declarate. Prelucrând următorul cuvânt din fluxul de intrare, procesorul caută prin dicționar și, găsind un cuvânt potrivit în acesta, efectuează acțiunile asociate cu acest cuvânt. Dacă căutarea nu a reușit, atunci, așa cum sa menționat deja, se încearcă interpretarea numerică a cuvântului, iar dacă aceasta nu reușește, urmează un mesaj că procesorul nu cunoaște cuvântul.
Ca rezultat al compilării unei definiții de procedură, numele acestei proceduri și indicatorul (adresa) corpului său, care este o secvență de pointeri către proceduri și date care compun definiția, sunt introduse în dicționar. Cu alte cuvinte, reprezentarea internă a corpului procedurii se obține prin înlocuirea denumirilor de proceduri și date din definiția sa cu pointerii corpurilor corespunzătoare, care la rândul lor sunt aceleași secvențe de pointeri, iar în cazul primitivelor, lanțuri. a instrucțiunilor mașinii. Numim această reprezentare internă a programului cod procedural.
Când, odată cu compilarea definițiilor procedurii P, sunt compilate definițiile tuturor procedurilor imbricate necunoscute anterior procesorului, se formează o ierarhie completă de pointeri care face posibilă executarea procedurii P furnizând numai numele acesteia către intrarea procesorului. În acest caz, numele procedurilor imbricate compilate în legătură cu definiția lui P, dacă nu trebuie să vă referiți la aceste proceduri separat, nu are sens să le stocați în dicționar. Într-o serie de cazuri, se dovedește a fi recomandabil să închideți accesul la una sau alta parte a dicționarului, lăsând, probabil, posibilitatea de a efectua doar unele proceduri.
Pentru a satisface astfel de cerințe, dicționarul este implementat ca o colecție de subdicționare, peste care sunt definite operațiuni care vă permit să creați și să distrugeți subdicționare și părțile lor, să ștergeți nume, să închideți și să deschideți accesul la anumite subdicționare. . Fiecare subdicționar are un nume care este folosit în comenzile aferente acestuia. Numele subdicționarelor trebuie să înceapă cu $, de exemplu: $ PRIME, $ EDIT, $ FLOAT, $ TEXTPROC, $ GRAPHICS.
Subdicționarul $ PRIME care conține setul de bază de cuvinte DSPP, după pornirea procesorului, este deschis atât pentru accesul la cuvintele pe care le conține, cât și pentru completarea cu cuvinte noi. Cuvintele noi introduse în el, dacă este necesar, pot fi șterse împreună cu corpurile asociate acestora cu comanda FORGET $ PRIME. După aceea, posibilitatea introducerii în continuare a cuvintelor în acest subdicționar este oferită prin executarea comenzii GROW $ PRIME, care permite ca subdicționarul $ PRIME să fie din nou mărit, iar tot ce este introdus în el poate fi din nou șters de FORGET $ Comanda PRIME etc. În acest mod, PRIME este utilizat atunci când se experimentează cu fragmente mici de programe, exemple individuale, estimări și, de asemenea, dacă este necesar, include cuvinte noi în subdicționarul $ PRIME în ordinea dezvoltării limbajului sistemului.
În cazul creării unui program separat, ei formează propriul dicționar pentru acesta, iar acest lucru se realizează prin faptul că textul programului începe cu comanda
PROGRAM $<имя программы>
O persoană percepe această comandă ca un antet, urmat de un comentariu între paranteze drepte, care caracterizează în câteva cuvinte funcția implementată de program. Pentru procesor, este echivalent cu o secvență de comenzi
UITA $<имя>CREȘTE $<имя>
Prin urmare, fiecare primire a textului programului la intrarea procesorului va provoca ștergerea versiunii sale anterioare și va deschide subdicționarul șters în acest mod pentru introducere. versiune noua program care poartă același nume. Acest lucru este convenabil atunci când faceți corecții la programul creat, precum și atunci când îl modificați în viitor.
Textul programului construit nu este introdus direct de la tastatură în intrarea procesorului, ci este format în tamponul editorului de text. Comanda E (Edit) setează modul de editare, în care cuvintele tastate pe tastatură nu mai sunt percepute de procesor ca comenzi de executat imediat, ci sunt pur și simplu text scris în buffer și afișat simultan pe ecran. Cu ajutorul tastelor speciale care controlează mișcarea indicatorului de poziție curentă (cursor) pe ecran, precum și comenzile de editare date prin apăsarea altor taste, textul introdus poate fi corectat și modificat, făcând ștergeri și inserări, transferând fragmentele acestuia din loc în loc etc.
La sfârșitul introducerii și editării textului, editorul este oprit prin apăsarea tastei E simultan cu (sau mai degrabă, cu tasta apăsată anterior)
Când descărcarea este completă, procedurile și datele sunt disponibile pentru referință după numele lor, tastate de la tastatură și puteți verifica corectitudinea programului executând procedurile în ordine crescătoare, adică. începând cu cei ale căror definiţii nu conţin proceduri neverificate. Înainte de a începe verificarea, este pertinent să vă asigurați că nu sunt folosite nume nedefinite în program. Procesorul le afișează pe ecran prin comanda UNDEF. Pentru a completa textul programului cu definiții ale acestor nume, precum și pentru a corecta alte erori detectate în timpul procesului de verificare, utilizați comanda E pentru a apela editorul și a face modificarea corespunzătoare a codului sursă al programului în buffer-ul editorului, apoi comutați procesorul în modul principal și încărcați conținutul tamponului cu comanda PF.
După verificarea și testarea programului, codul sursă al acestuia poate fi copiat din buffer-ul editorului pe disc folosind comanda OE f, unde f este numele fișierului sub forma căruia programul va fi scris pe disc. În viitor, conținutul fișierului poate fi încărcat în intrarea procesorului cu comanda LOAD f și, de asemenea, copiat în buffer-ul editorului ca o adăugare la textul din acesta cu comanda IE f. În mod implicit, fișierele au extensia .dsp. Buffer-ul poate fi șters în prealabil cu comanda KE. De asemenea, este posibil să imprimați conținutul buffer-ului cu comanda LPE.
După încărcarea programului, gata de execuție, este posibilă curățarea dicționarului creat $<имя>cu comanda CLEAR $<имя>... Executând această comandă, procesorul elimină numele necommitate din subdicționarul numit, de exemplu. toate numele, cu excepția celor cu prefix prefix :: (două două puncte) în fața definițiilor lor. În acest caz, sunt șterse doar numele în sine (intrări de dicționar), iar corpurile de proceduri și datele asociate acestora sunt salvate și disponibile în timpul execuției programului folosind legăturile interne stabilite în timpul compilării, dar acestea nu mai sunt disponibile din exterior. Pentru a restabili capacitatea de a accesa din exterior, de exemplu, dacă trebuie să compilați o adăugare sau modificare, trebuie să reîncărcați codul sursă al programului.
Numele pot fi făcute inaccesibile din exterior fără a le elimina din dicționar folosind comanda SHUT $<имя>, închizând accesul la toate cuvintele din subdicționarul numit. Deschiderea dicționarului pentru utilizarea cuvintelor sale se realizează prin comanda USE $<имя>... Există, de asemenea, NUMAI comanda $<имя>, care închide toate subdicționarele cu excepția celui numit și comanda CANCEL, care anulează această restricție. Comenzile enumerate vă permit să controlați utilizarea dicționarului în timpul compilării și să restricționați setul de nume disponibile pentru utilizatorul programului la minimum necesar.
Căutarea unui nume în dicționar se face prin privirea cuvintelor acestuia în ordinea inversă celei în care au fost introduse în dicționar, adică. începând cu ultimul introdus. Prin urmare, pentru un nume definit de mai multe ori în dicționar, cea mai recentă definiție este valabilă. Dacă subdicționarul care conține această ultimă definiție este închis, atunci căutarea continuă până la prima intrare de dicționar disponibilă cu numele dat și definiția indicată de această intrare va fi folosită.
Câteva cuvinte despre intrarea și ieșirea datelor. După cum sa menționat deja, procesorul încearcă să interpreteze cuvântul programului executabil care nu se găsește în dicționar ca un număr și, dacă reușește, împinge echivalentul binar al acestui număr în stivă. Introducerea unui număr în stivă poate fi efectuată prin comanda TIN, care necesită tastarea numărului introdus pe tastatură. Există și comenzi pentru împingerea unui caracter introdus de la tastatură pe stivă: TIB - cu afișaj, TRB - fără afișarea acestui caracter pe ecran. În acest caz, codul literei este reprezentat de octetul cel mai puțin semnificativ al cuvântului de 32 de biți împins pe stivă, dintre care cei mai semnificativi 3 octeți sunt egali cu zero.
Conținutul din partea de sus a stivei poate fi introdus ca număr și, respectiv, ca literă. Comanda TON determină afișarea valorii numerice a subliniei în câmpul de ieșire, a cărei lățime este stabilită de vârf, în sistemul de reprezentare a numerelor setat la momentul execuției sale. Comanda TOB tipărește pe ecran un caracter al cărui cod este conținut în octetul inferior din partea de sus a stivei. În ambele cazuri, rezultatul este însoțit de eliminarea argumentelor din stivă.
Procesorul DSPP are un aparat pentru întreruperi externe și interne (de comandă) și oferă următoarele mijloace de procesare a acestora. Procedura de gestionare a unei întreruperi externe este definită în mod similar cu o procedură normală, dar cu prefixul INT adăugat înainte de două puncte. Numele unei astfel de proceduri este asociat cu adresa vectorului de întrerupere cu comanda:
<адрес вектора>LEGĂTURĂ<имя процедуры>
O întrerupere de comandă este o operație numită care apelează o procedură de răspuns. Denumirea acestei operații este determinată de comanda TRAP, care o asociază cu o așa-numită procedură de răspuns final, efectuată în cazul în care răspunsul final nu este înlocuit cu comanda ON sau EON printr-o altă procedură de răspuns. Toate cele trei comenzi au același format:
CAPCANĂ<имя вызова> <процедура реагирования>
PE<имя вызова> <процедура реагирования>
EON<имя вызова> <процедура реагирования>
Procedura asociată numelui apelului de către comanda EON se execută cu o ieșire preliminară din corpul procedurii care conține comanda EON și cu valoarea pointerului stivei de operanzi care a apărut la momentul execuției EON.
Sintaxa PARADIS
Alfabetul limbii PARADISE include latină și rusă, litere mari și mici, cifre zecimale, caractere matematice și alte caractere speciale. Elementele (membrii) alfabetului se numesc litere. Reprezentarea externă a unei litere este imaginea ei imprimată (semn tipărit). În interiorul procesorului PRSP, fiecare caracter imprimat este reprezentat de un octet, a cărui valoare este codul binar al acestui caracter. Transformarea reprezentării externe în cea internă și invers se realizează de către dispozitivul de intrare/ieșire (tastatură, afișaj, imprimantă). Pentru confort valoare numerică codurile sunt exprimate în sistem zecimal, hexazecimal sau octal, denumind numărul corespunzător în codul de caractere zecimal, hexazecimal sau octal.
Toate obiectele limbajului PARADIS sunt construite din litere și reprezintă lanțuri liniare de litere de lungime finită, numite cuvinte. Separatorul cuvintelor care urmează unul altuia este un caracter neimprimabil (spațiu). Un șir de spații este același cu un spațiu. În plus, funcția separatorului de cuvinte este îndeplinită de comanda „Mergeți la începutul liniei următoare”, notat pe tastaturile dispozitivelor de intrare prin simbolul
Exemple de cuvinte: CLEAR NOP STEK2 & 1+ -366 X Sample.
Procesorul DSPP distinge cuvintele prin primele șapte litere, identificându-le prin comparație polimerică cu cuvintele din dicționarul său. Dicționarul conține cuvinte care sunt denumirile (denumirile) operațiilor proprii ale procesorului, numite operații de bază sau primitive, și pot fi completate cu denumirile obiectelor definite de utilizator (date, proceduri). Astfel, cuvintele conținute în dicționar sunt fie nume de acțiuni (operații, proceduri), fie denumiri de date (constante, variabile, tablouri).
Când nu există niciun cuvânt recunoscut în dicționar, procesorul încearcă să-l atribuie unuia dintre următoarele cazuri:
literal numeric, adică o succesiune de numere, eventual începând cu semnul minus, de exemplu: 0, 4096, -25;
caracter literal: un cuvânt care începe cu caracterul #, care face ca procesorul să primească caracterul imediat următor ca cod dat, de exemplu: #A - litera latină majusculă A literal, # 5 - cifra 5 literală, # - spațiu literal, ## - litere literale #;
text literal: text arbitrar cuprins între ghilimele duble și separat prin delimitatori de cuvinte, de exemplu: „Text”, „Fișier de intrare N3”;
comandă pentru a trimite un mesaj text pe afișaj: textul mesajului afișat, delimitat la stânga prin ghilimele punct-duble și ghilimele duble la dreapta și separat prin delimitatori de cuvinte, de exemplu: „Stiva este goală ";
comentariu: text arbitrar cuprins între paranteze pătrate și separat prin separatoare, de exemplu:.
Literale și comanda pentru emiterea unui mesaj pe afișaj acționează ca obiecte ale limbajului DSPP împreună cu cuvintele recunoscute de dicționar, în timp ce comentariile sunt complet ignorate de procesorul DSPP - sunt destinate unei persoane, nu unei mașini. Dacă cuvântul nu se găsește în dicționar și nu are legătură cu construcțiile enumerate, procesorul emite un mesaj: „Nu știu<неопознанное слово>".
Datorită semnificației speciale acordate literelor #, „și combinația”. la începutul unui cuvânt, adică după separator, precum și litera „înainte de separator, acestea nu trebuie folosite în pozițiile indicate în cuvintele determinate pentru includerea în dicționar.
O secvență de cuvinte la intrarea procesorului este interpretată ca o secvență de instrucțiuni executate de procesor. În acest caz, se disting trei tipuri de cuvinte:
1) efectuat independent, adică care sunt comenzi cu un singur cuvânt (monologii);
2) efectuată împreună cu unul sau mai multe cuvinte ulterioare, i.e. care sunt cuvintele inițiale (prefixele) ale comenzilor cu două, trei sau verbose;
3) precedarea comenzii ca o precizare sau o indicație a unui mod special de execuție (pre-prefixe).
Monologii includ literale, nume de date, majoritatea I/O, testarea și conversia datelor din stivă și rutine definite de utilizator. De exemplu: 1987 - literal numeric, # 5 - cifra 5 literal, Lista Schema - literal text, LUNGIME - nume variabilă, TOB, NEG, +, &,<, = - имена (обозначения) операций, SORT, CONVERT, ЧИСТКА, СНЯТЬ - имена процедур пользователя.
Prefixele sunt inerente comenzilor pentru descrierea datelor și definirea procedurilor, precum și manipularea datelor cu nume, execuția condiționată și repetată a procedurilor și gestionarea dicționarului. Exemple de comenzi cu prefixe:
VAR SUM - creați o variabilă SUM,
: ODD [x] 1 &; - creați o procedură IMPAR care înlocuiește un număr impar cu 1, par cu 0,
0 X - atribuiți valoarea 0 variabilei X,
BR + P1 P2 - dacă valoarea vârfului său luată din stivă este pozitivă, atunci executați P1, în caz contrar executați P2,
RP CHECK - executați procedura de VERIFICARE din nou și din nou,
USE $ REAL - deschideți subdicționarul $ REAL pentru utilizare.
De obicei, un prefix specific necesită un anumit număr de cuvinte după el. Deci, în exemplele tocmai date, prefixele VAR,! 0 și USE necesită câte un cuvânt, iar prefixul BR + necesită două cuvinte. Cu toate acestea, prefixul: (colon) vă permite să formați o comandă de lungime arbitrară, începând cu trei cuvinte. Sfârșitul comenzii este cuvântul; (punct şi virgulă). Lungimea arbitrară este, de asemenea, inerentă comenzii - descriptor constant CNST A1 ... AJ; iar procedura comanda alegere multipla BR A1 P1 ... AJ PJ ELSE PN.
Prefixele sunt cuvinte speciale care, atunci când sunt adăugate în fața unei comenzi, îi modifică conținutul sau definesc un mod special de execuție. De exemplu, comanda VAR X fără prefix este o instrucțiune pentru a crea o variabilă X pe 16 biți. Dacă îi atașați prefixul BYTE, obținem comanda BYTE VAR X, care indică crearea unei variabile pe 8 biți. (octet) numit X. Dacă utilizați prefixul LONG, atunci obținem LONG VAR X - o instrucțiune pentru a crea o variabilă de 32 de biți numită X.
Un prefix de alt tip, și anume :: (două două puncte), face ca rezultatul comenzii să fie rezistent la procedura CLEAR, care elimină cuvintele nefixate din dicționar. Numele introduse în dicționar în procesul de construire a unui program prin comenzi pentru descrierea datelor și definirea procedurilor, după ce programul a fost creat și testat, pot fi eliminate din dicționar, cu excepția câtorva care sunt necesare pentru a menține program terminat. Îndepărtarea se efectuează cu comanda CLEAR $<имя подсловаря>, indicând să ștergeți dicționarul asociat programului, păstrând în el doar acele cuvinte ale căror definiții conțin prefixul ::. Exemple de comenzi care generează cuvinte care nu pot fi îndepărtate:
:: BYTE CNST LITCODE # # 0 #A;
::: MOD / [int (a, b), rest (a, b)] E2 D [odihnă (a, b)];
După cum arată cel de-al doilea exemplu, care conține prefixele :: și BYTE, poate exista mai multe prefixe într-o comandă.
Astfel, o comandă din DSPP poate fi fie un singur cuvânt (monolog), fie o frază (expresie) care începe cu un prefix și conține numărul de cuvinte setat pentru un prefix dat, iar dacă prefixul permite un număr arbitrar de cuvinte , apoi are un cuvânt delimitator la sfârșit sau poate fi o frază cu cuvinte speciale pre-prefix în fața ei.
Limbajul de bază al DSPN nu conține construcții sintactice mai complexe decât comanda și nu conține alte construcții decât cele discutate mai sus. Chiar și lucruri indispensabile în limbajele de programare, cum ar fi o expresie și o funcție, sunt absente în limbajul de bază și pot fi introduse, dacă este necesar, numai în cursul dezvoltării sale.
Un program într-un limbaj de bază este pur și simplu o colecție de comenzi executate în ordinea în care apar în text. Mai mult, fiecare comandă, cu excepția celor care conțin doar primitive, în procesul de execuție a acesteia implică o succesiune de comenzi care definesc cuvintele incluse în ea. Comenzile implicate pot conține, la rândul lor, cuvinte care denotă lanțuri de comenzi, în care sunt posibile și cuvinte care se referă la lanțurile lor asociate etc. până la nivelul la care comenzile conţin doar primitive.
Descrierea generală a limbajului PARADISE, care a constituit conținutul acestui capitol, a fost dedicată caracteristicilor structurii acestui limbaj și setului de bază (inițial) al comenzilor sale, care este un set de comenzi încorporate (primitive) a procesorului DSPP. Dezvoltarea ulterioară a limbajului și creșterea corespunzătoare a capacităților procesorului se realizează prin introducerea de noi proceduri, comenzi, formate și tipuri de date, construite folosind instrumente de bază. De regulă, o astfel de dezvoltare este orientată către probleme și se realizează sub formă de pachete de proceduri încărcate la intrarea procesorului în plus față de sistemul de bază.
Pe de altă parte, sistemul de bază poate fi completat cu instrumente speciale pentru creșterea eficienței mașinii a programelor DSP implementate pe baza acestuia. Aceste instrumente includ capacitatea de a defini proceduri individuale direct în codul de instrucțiuni al mașinii utilizate. Modul în care este definită o procedură nu are niciun efect asupra utilizării sale ulterioare: numele tuturor procedurilor sunt introduse într-un dicționar comun și sunt complet egale. O serie de programe de bibliotecă vă permit să utilizați proceduri sau programe întregi scrise în alte limbi.
Descrierea operațiunilor și comenzilor
Operațiuni de stivă
Stiva de operanzi este unul dintre elementele principale ale arhitecturii procesorului DSP. Majoritatea instrucțiunilor procesorului folosesc stiva, consumând operanzii de care au nevoie din el și împingând rezultatele în ea. Interpretarea datelor din stivă depinde de esența problemei care se rezolvă, adică este încredințată în cele din urmă programatorului. Din cauza faptului că valoarea care a intrat în stivă își pierde de fapt numele, este greu de determinat din textul programului căror operanzi se aplică cutare sau cutare operație, care sunt rezultatele acesteia. Prin urmare, pentru o indicare explicită a operanzilor și a rezultatelor procedurilor în limbajul PARADISE, sunt folosite comentarii. În acest caz, nu este necesar (și nu întotdeauna posibil) să descrieți întregul conținut al stivei. Este absolut necesar să comentați partea superioară a stivei, care este afectată de procedura efectuată pe aceasta, deoarece fără aceasta vizibilitatea programului se pierde și verificarea acestuia devine dificilă.
Pentru a obține coerența programului, aceste comentarii ar trebui scrise cu câteva reguli simple. Ca orice comentariu, descrierea datelor de pe stivă este inclusă între paranteze drepte. Această descriere este o listă a operanzilor care se află pe stivă la un anumit punct al programului. Fiecare element al listei caracterizează conținutul unei poziții de stivă, o virgulă este folosită ca separator. Pozițiile stivei sunt listate de la stânga la dreapta, începând cu cel mai adânc element și terminând în partea de sus a stivei. Descrierea unui operand individual poate fi un număr, un nume, o expresie sau orice altă înregistrare semnificativă care explică semnificația valorii de pe stivă. Uneori puteți specifica mai multe valori posibile pentru o anumită poziție a stivei. În acest caz, valorile sunt enumerate cu o bară oblică.
Iată un exemplu de comentariu care reflectă starea stivei de operanzi:
[adresa de start, N + 1,1 / 0]
În punctul din program în care se află acest comentariu, stiva de operanzi trebuie să conțină cel puțin trei poziții, iar în partea de sus poate fi 1 sau 0, în sub-secțiune - o valoare numerică egală cu N + 1 și mai jos it - un număr interpretat ca adresa de pornire.
Pentru confortul de a specifica poziția necesară a stivei, vom folosi conceptul de adâncime. Vom presupune că partea superioară a stivei se află la adâncimea 1, substratul este la adâncimea 2 și așa mai departe. În special, valoarea indicată în exemplu ca „începe anunț”. se află la o adâncime de 3.
Vom începe studiul limbajului de bază DSPC cu comenzile pentru împingerea valorilor pe stivă. Cea mai simplă (și cel mai frecvent utilizată) comandă de acest tip este un literal numeric, adică o indicație explicită a unei constante care trebuie împinsă în stivă. De exemplu, să presupunem că vrem să împingem în stivă numerele 28, -5 și 11. Pentru a face acest lucru, introduceți următorul șir de la tastatură:
28 -5 11 și apăsați tasta
Pentru a afișa întregul conținut al stivei, DSPP conține comanda .. (două puncte). După ce o executăm, obținem linia pe ecran:
După cum puteți vedea, forma tipăririi urmează convențiile acceptate pentru comentarea stării stivei (cu excepția faptului că se folosește un spațiu în loc de virgulă). Comanda .. nu modifică conținutul stivei.
Un cuvânt de 32 de biți (4 octeți) este utilizat pentru a reprezenta o poziție a stivei în memoria mașinii, numerele sunt reprezentate în codul de complement a doi. În consecință, procesorul PRSP poate percepe corect numai numerele întregi situate în intervalul de la -2147483648 la 2147483647. Dacă numărul introdus nu este reprezentabil cu 32 de biți (cu semn), atunci cei mai semnificativi biți care nu se potrivesc sunt aruncați.
În exemplele luate în considerare, s-a presupus că procesorul PRSP se află în modul zecimal de intrare/ieșire a numerelor. Pentru a seta acest mod în limba PARADISE există o comandă B10.
În multe sarcini, este necesar să se interpreteze datele procesate nu ca numere, ci ca coduri binare, adică vectori de biți cu 32 de componente. În DSPP este posibil să se lucreze cu coduri prezentate în sistem de numere binar, octal sau hexazecimal. Pentru a seta modul dorit, este suficient să executați una dintre cele trei comenzi: B2, B8 sau B16, după care procesorul va percepe și imprima toate codurile introduse în sistemul de numere specificat.
Această caracteristică poate fi folosită pentru a converti numere zecimale în baza 2, 8 și 16. De exemplu, pentru a converti numărul 29, trebuie să introduceți și să executați următoarea linie:
B10 29 B2. B8. B16. Ca rezultat, procesorul va afișa o serie de numere: 00000000035 0000001D care sunt reprezentări ale numărului zecimal 29 în cele trei sisteme numerice specificate. Rețineți că codurile sunt tipărite în reprezentarea mașinii lor, adică cu zerouri înainte și fără semnele „+”, „-”. La executarea liniei B10 -2 B8. va fi returnat numărul 37777777776, care este reprezentarea octală a complementului a doi al lui -2.
Când lucrați cu coduri hexazecimale, pot apărea coliziuni între literalele numerice și numele comenzilor procesorului DSPP. De exemplu, cuvântul B8 în modul I/O hexazecimal poate fi interpretat ca o comandă pentru a seta modul octal și ca o constantă hexazecimală. Pentru a evita ambiguitatea, începeți literalele numerice cu un zero nesemnificativ, cum ar fi 0B8.
Baza sistemului de instrucțiuni al procesorului DSPP este alcătuită din operațiunile de conversie a datelor din stivă. Regula generală care guvernează operarea acestor operații este că fiecare operație consumă (elimină) operanzii necesari din stivă și împinge valorile rezultatului (dacă există) în locul lor.
Luați în considerare instrucțiunile procesorului care implementează patru operații aritmetice: adunarea, scăderea, înmulțirea și împărțirea numerelor întregi. Pentru a le reprezenta în limba PARADIS, sunt folosite cuvintele: +, -, * și respectiv /. Pentru a obține suma a două numere de pe stivă, de exemplu 123 și 45, trebuie să împingeți aceste numere pe stivă și să executați comanda +. Pentru a face acest lucru, este suficient să introduceți următoarea linie de la tastatură (se presupune că modul I / O zecimal este setat):
123 45 +
Dacă afișăm acum conținutul stivei (folosind comanda ..), rezultatul adăugării va deveni vizibil:
Operația de înmulțire comutativă funcționează în mod similar.
Atunci când se efectuează operații de scădere și împărțire necomutative, sub-stiva este luată drept scădere (dividend), iar partea de sus este scădere (divizor). De exemplu, pentru a calcula diferența 151-68, trebuie să executați linia:
151 68 -
Un program pentru efectuarea unei operații aritmetice în limbajul PARADISE se caracterizează prin faptul că operația este localizată după operanzii corespunzători. Această notație a expresiilor aritmetice se numește notație postfixă (sau inversă poloneză) și este utilizată pe scară largă în calculatoarele stivuite. Să presupunem, de exemplu, că trebuie să calculăm valoarea expresiei aritmetice ((127 + 81) * 15- (31 + 117) * 21) * 3
În notația postfix, această expresie va arăta astfel:
127 81 + 15 * 31 117 + 21 * - 3 *
Această linie (în care cuvintele sunt separate unele de altele prin spații) este un program gata făcut pentru calcularea expresiei noastre de către procesorul DSP.
Diviziunea / comanda diferă de alte operații aritmetice prin faptul că rezultatul său este două valori - coeficient și rest. Coeficientul este în partea de jos a stivei, iar restul este în partea de sus. Coeficientul este negativ dacă dividendul și divizorul sunt semne diferite. Restul are întotdeauna semnul dividendului. Iată câteva exemple de utilizare a comenzii de divizare.
125 7 / [-17,-6] / / /
La efectuarea calculelor pot apărea situații eronate: debordare și împărțire la zero. Procesorul DSPP nu reacționează la ele în niciun fel (în special, la împărțirea la zero, conținutul stivei nu se schimbă), iar controlul asupra corectitudinii utilizării operațiunilor este atribuit programatorului.
La programare, este adesea necesară creșterea sau scăderea valorii unei valori cu 1 sau 2. Au fost introduse comenzi speciale în limbajul PARADISE care efectuează acțiunile indicate în partea de sus a stivei. Ele sunt indicate prin cuvintele: 1+, 1-, 2+, 2-. Executarea acestor comenzi echivalează cu împingerea constantei necesare (1 sau 2) pe stivă și apoi efectuarea operației aritmetice necesare (+ sau -). De exemplu, 2+ este echivalent cu perechea de cuvinte 2 +. Introducerea în limbajul acestor comenzi se face din motive de eficiență.
De asemenea, pentru a îmbunătăți eficiența în limbajul de bază al procesorului DSP, există comenzi T0 și T1 care înlocuiesc valoarea vârfului stivei cu 0 și respectiv 1, indiferent de ce valoare era în vârf înainte de comanda specificată. Exemple:
Comenzile NEG, ABS și SGN sunt, de asemenea, disponibile pentru lucrul cu date numerice. Comanda NEG inversează semnul vârfului stivei, ABS înlocuiește valoarea vârfului stivei cu modulul său, SGN - consumă o valoare numerică din vârful stivei și înlocuiește semnul numărului extras: -1 - dacă numărul este negativ, 1 - dacă este pozitiv, 0 - dacă este egal cu zero. De exemplu:
5 NEG [-5] ABS SGN
Comenzile MIN și MAX din limba de bază vă permit să găsiți minimum și maxim de două numere întregi. Operanzii acestor instrucțiuni sunt două numere în partea de sus și de jos a stivei. Instrucțiunea MIN lasă pe stivă cel mai mic dintre numărul de parametri, MAX maximul dintre ei. De exemplu:
5 0 15 MIN [-5,0] MAX
Pentru a găsi minimul (maximum) dintre cele trei numere din stivă, trebuie doar să utilizați comanda MIN (MAX) de două ori:
MIN MIN [-2]
Comanda SEG pentru a verifica dacă numărul conținut în partea de sus a stivei se încadrează în intervalul specificat de la a la b (inclusiv granițele) lasă un semn pe stivă ca rezultat: 1 dacă numărul este în interval și 0 dacă nu:
SEG [funcție] de exemplu:
Pe lângă instrucțiunile de lucru cu date numerice, setul de instrucțiuni pentru procesorul DSPP include o serie de operațiuni concepute pentru a converti coduri pe 32 de biți. Aceste operații tratează elementul stivă ca pe un vector de biți cu 32 de componente, ale căror componente sunt numerotate de la dreapta la stânga astfel încât bitul din stânga să fie numărul 31, iar cel din dreapta să fie 0. Numerotarea descrescătoare a componentei repetă numerotarea biților de cuvinte mașini acceptate pentru multe microprocesoare.
Comenzile executate pe vectori de biți includ în principal operații pe biți ale algebrei booleene:
inversarea pe biți a vârfului stivei INV, schimbând valoarea fiecărui bit din partea de sus, adică înlocuirea 0 cu 1 și 1 cu 0;
conjuncția pe biți a părții de sus și de jos a stivei &, setând al-lea bit al rezultatului, i = 31,30, ..., 0, la 1 dacă i-ai biți ai ambilor operanzi sunt egali cu 1 , iar în alte cazuri setarea i-lea bit egal cu 0;
o disjuncție pe biți a părții de sus și de jos a stivei & 0, setând în al-lea bit al rezultatului, i = 31,30, ..., 0, valoarea 0, dacă i-ai biți ai ambilor operanzi sunt egale cu 0, iar în alte cazuri setând al-lea bit egal cu 1;
adăugare pe biți (neechivalență) „+” a nodurilor și sub-nodurilor, care setează i-lea bit al rezultatului la 0 dacă i-lea biți ai ambilor operanzi au aceleași valori și setează i-lea bit bit din rezultat la 1 dacă valorile biților i ai operanzilor sunt diferite.
525 INV 722 și 136 și 0 325 „+”
Conjuncția pe biți este adesea folosită pentru a elimina (șterge) biții de cuvânt. Pentru a face acest lucru, combinați cuvântul original cu o mască care conține zerouri în cifrele care trebuie șters și cele în cifrele rămase. De exemplu, dacă trebuie să zero biți de la 3 la 5 într-un cuvânt X, trebuie să efectuați conjuncția sa pe biți cu masca 37777777707. Pentru X = 235, obținem:
Disjuncția pe biți poate fi utilizată pentru a insera modelul de biți dorit într-un grup de cuvinte pre-șters. De exemplu, să presupunem că doriți să puneți combinația binară 010 în biții de la 3 la 5 ai cuvântului rămas în stivă ca rezultat al ultimului exemplu. O poți face astfel:
Operațiile de manipulare a biților includ, de asemenea, comenzi de schimbare logică:
deplasare la stânga SHL - fiecare bit din vârful stivei, începând cu al 31-lea, ia valoarea următorului în ordinea descrescătoare a numerelor, iar ultimul bit, zero, ia valoarea 0;
dreapta shift SHR - fiecare bit din vârful stivei, începând de la 0, ia valoarea următorului în ordinea crescătoare a numerelor, iar al 31-lea bit ia valoarea 0;
deplasare de-a lungul SHT de sus - elementul de sus este scos din stivă și tratat ca un întreg N, indicând câte schimbări și în ce direcție ar trebui efectuate în partea de sus a stivei: când N> 0, se face o deplasare către stânga, când N<0 - вправо.
B8 125 SHR SHL -2 SHT
Operațiile de deplasare la stânga pot fi folosite pentru a înmulți numerele cu 2 până la a N-a putere, unde N este un număr natural care determină numărul de schimburi. De exemplu, înmulțirea numărului -5 cu 8 se poate face prin deplasarea acestui număr cu 3 cifre la stânga:
B10 -5 3 SHT [-40]
În acest caz, ar trebui să se țină cont de posibilitatea de depășire.
Deplasarea la dreapta poate fi folosită ca operație de împărțire în întregime cu 2 la puterea lui N numai pentru numere pozitive, deoarece bitul cel mai semnificativ (semn) este pus la zero atunci când se deplasează la dreapta. De exemplu:
întrucât
Comenzile pentru a roti partea superioară a stivei cu 1 bit spre ROR dreapta și ROL stânga sunt similare cu comenzile de schimbare logică, cu excepția faptului că bitul extrem extins nu dispare, ci este împins în spațiul liber de la capătul opus al unui Cuvânt lung de 32 de biți. De exemplu (numere hexazecimale):
Pentru procesarea codurilor binare sunt destinate și comenzile procesorului DSPP SWB și SWW. Funcția SWB este de a schimba octeții din jumătatea inferioară a vârfului stivei, iar funcția SWW este de a schimba jumătățile din partea de sus a stivei. Să ilustrăm funcționarea acestor comenzi folosind modul I/O hexazecimal (în acest mod, fiecare octet este reprezentat de două cifre hexazecimale):
B16 0ABCD SWB SWB
0ABCDEF12 SWW SWB
Instrucțiunile de manipulare a stivei joacă un rol important în limbajul PARADISE. Ele nu modifică valorile datelor de pe stivă, ci doar le schimbă locația, facilitând accesul operanzilor aflați adânc în stivă.
Există trei comenzi pentru ștergerea membrilor stivei: D, DD, DS (Drop). Comanda D elimină un element (de sus) din stivă, DD - două elemente, de exemplu:
D DD D DS elimină toate elementele din stivă (șterește stiva):
Comanda pentru copierea vârfului stivei C (Copy - copy) împinge pe stivă o copie a valorii curente a vârfului său. Acest lucru echivalează cu duplicarea elementului superior al stivei: vechiul top devine sub, iar copia sa devine noul top. Exemplu:
Să arătăm aplicarea acestei comenzi prin exemplul de calcul al polinomului p (x) = 3 * x ** 2 + 4 * x-5 conform schemei lui Horner: p (x) = (3 * x + 4) * x -5. Presupunem că x este în vârful stivei.
[x] C 3 * 4 + * 5 -
Alături de comanda pentru copierea vârfului stivei în limbajul PARADISE, există și comenzile C2, C3, C4, care copiază elemente situate la adâncimile 2, 3, 4. Lucrarea lor poate fi ilustrată prin următoarele exemple:
C2 C4
Există, de asemenea, o comandă CT pentru a copia articolul la adâncimea indicată în partea de sus a stivei. Executând CT, procesorul scoate elementul de sus din stivă, folosește valoarea acestuia ca un indicator al adâncimii elementului copiat și împinge o copie a acestuia din urmă pe stivă. Deci, copierea unui element situat la o adâncime de 5 este setată de o pereche de 5 comenzi CT, atunci când este executată, procesorul va împinge numărul 5 pe stivă și apoi va executa comanda CT. Executarea CT cu parametrii 1, 2, 3, 4 este echivalentă cu C, C2, C3, respectiv C4.
Comenzile de schimb E2, E3, E4 (Schimb - schimb) efectuează permutarea primului element (de sus) al stivei, respectiv, cu al 2-lea, al 3-lea, al 4-lea, adică cu elementul situat la adâncimea de 2, 3. , 4. De exemplu:
E3 E2
Pentru a schimba cu adâncime mai mare, se folosește comanda ET, care, la fel ca CT, folosește valoarea vârfului stivei ca indicator al adâncimii elementului, care este schimbată cu primul element. De exemplu:
5 ET
Comanda ET cu parametrii 2, 3, 4 este echivalentă cu comenzile E2, E3, E4.
Pentru a ilustra utilizarea comenzilor de copiere și partajare, luați în considerare o problemă de tutorial. Teancul conține trei numere. Este necesar pentru a intra pe stiva:. Se poate propune următorul program, al cărui sens este clar din comentarii.
C3 C3 C3 +
E4 + E4
Acest exemplu arată cât de important este rolul comentariilor, care reflectă starea stivei de operanzi.
Programele trebuie adesea să compare valorile numerice între ele și să efectueze diverse proceduri în funcție de rezultatele comparației. Există comenzi de comparare în limbajul PARADISE<, =, >... Ele sunt definite peste numere și returnează ca rezultat valorile numerice 0 și 1. De exemplu, comanda< потребляет из стека два элемента и засылает в стек число 1, если значение нижнего элемента оказалось меньше значения верхнего, а в противном случае засылает 0. Например, в результате выполнения последовательности 5 -20 < в стек будет заслан 0. Команда = засылает 1 в случае равенства потребленных ею элементов. Команда >trimite 1 când elementul de jos este mai mare decât cel de sus. Pentru a programa comparații nestricte (mai mici sau egale, mai mari sau egale), utilizați comanda NOT, care înlocuiește o valoare diferită de zero din stivă cu zero, dar zero cu unul. De exemplu, evaluarea expresiei logice x> = 5, unde x este un număr situat în partea de sus a stivei, poate fi specificată după cum urmează:
[x] 5< NOT
Extinderea în continuare a posibilităților de programare a condițiilor este asigurată de utilizarea, împreună cu comenzile de comparare, a operațiilor logice de conjuncție & (ȘI logic) și disjuncție & 0 (SAU logic). Să fie, de exemplu, este necesar să obținem 1 pe stivă dacă numărul x de la vârf aparține semisegmentului C 5< NOT C2 10 <
& E2 2 = & 0
Controalele programului în funcție de rezultatele comparației vor fi discutate mai târziu.
Definirea procedurilor
Ca tehnică de programare de bază, PRSP oferă utilizatorului abilitatea de a defini secvențe numite de operațiuni numite proceduri. Să fie necesar, de exemplu, să se calculeze valorile trinomului pătrat 3 * x ** 2-4 * x + 9 pentru valorile date ale lui x. În acest caz, ar trebui să definiți o procedură care implementează formula trinomială și să scoată rezultatul către terminal, apoi să aplicați această procedură la anumite valori ale lui x. Procedura necesară, să o numim PX, este definită după cum urmează:: PX [x] C 3 * 4 - * 9 +. D; Punctele două puncte denotă o operațiune „definiți procedura”, cu numele procedurii urmat de două puncte după un spațiu de separare. Secvența definitorie de comenzi (corpul procedurii) urmează numele procedurii și se termină cu punct și virgulă. Pe scurt, procedura este definită sub forma:
: <имя процедуры> <тело процедуры> ;
În limbajul PARADISE, este necesar să comentați starea stivei de operanzi la începutul și la sfârșitul procedurii. În corpul procedurii, comentariile sunt plasate la latitudinea programatorului în locuri greu de înțeles.
Comentariile ajută o persoană să înțeleagă și să folosească procedura, în timp ce procesorul pur și simplu ignoră totul în paranteze. Prin urmare, dacă introduceți definiția unei proceduri individuale din terminal, puteți omite comentariile.
După ce a fost introdusă definiția procedurii și prin apăsarea tastei
* 2 PX
* 3 PX
* 4 PX
Să definim o procedură mai generală pentru calcularea unui trinom de forma a2 * x ** 2 + a1 * x + a0, care ne permite să specificăm valorile ambelor x și a0, a1, a2. Să-i spunem PXA:
: PXA C E4 E3 * + * +;
Când utilizați PXA, valorile a0, a1, a2, x trebuie să fie în secvența necesară pe stivă. De exemplu: a0 = 1, a1 = 2, a2 = -3, x = 4
* 1 2 -3 4 PXA. D
În corpul unei proceduri, împreună cu operațiunile de bază ale procesorului, pot exista proceduri definite de utilizator. De exemplu, puteți defini o rutină P care, pe lângă calculele PXA, va scrie o copie a rezultatului pe terminal și va elimina rezultatul din stivă.
: P PXA. D;
În special, corpul unei proceduri poate include numele procedurii care este definită în sine, adică procedura poate fi recursivă. De exemplu:
: TIME [t] 1- TIME;
Această procedură scade valoarea vârfului stivei cu 1 și se referă din nou la sine, adică funcționează ca un contor de timp.
Contorul TIME, în principiu, nu se poate opri: procedura de scădere a unuia va fi efectuată iar și iar atâta timp cât procesorul funcționează. Dar în DSPP există mijloace care vă permit să controlați cursul procesului în funcție de rezultatele obținute - operația de control al cursului programului.
Execuție și repetare condiționată
Un program, care este o succesiune de comenzi executate în ordinea locației lor una după alta în înregistrarea sa, se numește liniar. Pentru a face programul ușor de observat (lizibil) și de înțeles, acesta este împărțit în părți numite care au o anumită semnificație - proceduri, fiecare definită de propria succesiune de proceduri, care la rândul lor sunt definite de secvențe de proceduri mai mici etc. la proceduri definite direct de secvențe de comenzi DSPP. Un astfel de program, scris ca o ierarhie a definițiilor procedurilor, se numește structurat. Metoda de construire a unui program structurat, care constă în descompunerea treptată a problemei fiind rezolvată în subsarcini din ce în ce mai mici, se numește programare structurată.
Crearea nu numai a programelor liniare, ci și a oricăror programe prin metoda de programare structurată este posibilă dacă există operații pentru executarea procedurii după condiție, repetarea procedurii și ieșirea din procedura repetată. Setul de comenzi de acest fel disponibil în DSPP oferă posibilitatea unei construcții structurate a unui program arbitrar.
Conditiile de executare sau neexecutarea procedurii se formuleaza relativ la semnul numarului, mai exact, raportat la semnul valorii pe care o poseda in prezent varful stivei. Comanda principală a execuției condiționate a procedurii - BRS (BRanch on Sign - to branch by sign) indică executarea uneia dintre cele trei proceduri denumite după BRS, în funcție de semnul valorii curente a vârfului stivei. În timp ce execută BRS, procesorul scoate elementul de sus din stivă, îi testează valoarea și, dacă este negativ, execută prima dintre procedurile numite, dacă este egală cu zero, apoi a doua, iar dacă este pozitivă, atunci a treia. . Deci echipa
va determina eliminarea unui element din stivă și executarea procedurii N dacă valoarea eliminată este negativă, executarea procedurii P dacă este pozitivă și executarea procedurii Z dacă este zero.
Un exemplu de utilizare a comenzii BRS este următoarea definiție proceduri SGN
: SGN [X] BRS -1 0 1;
Această rutină înlocuiește valoarea X din partea de sus a stivei cu -1 dacă X<0, числом 0, если X=0, и числом 1, если X>0. Procedura SGN este disponibilă în PRSP ca operațiune de bază a procesorului.
Comanda BRS, împreună cu alegerea unei proceduri din trei date, oferă posibilitatea implementării operatorilor din două cifre de forma IF-THEN și IF-THEN-ELSE. De exemplu, afirmația dacă x> 0 atunci P1 altfel P0 corespunde comenzii BRS P0 P0 P1, iar instrucțiunea dacă x<>0 apoi P - BRS P NOP P comanda, unde NOP este numele unei operații goale. Dar în DSPP există o implementare mai eficientă a condițiilor din două cifre - comenzile IF-, IF0, IF +, BR-, BR0, BR +.
Comenzile IF corespund instrucțiunii IF-THEN. De exemplu, instrucțiunea IF-P indică să scoateți elementul de sus din stivă și să testați semnul acestuia, iar dacă acest element are semnul minus, atunci executați procedura P. Instrucțiunile IF0 P și IF + P indică executarea P procedură, respectiv, în cazul în care elementul izbit este egal cu zero și în cazul în care valoarea acestuia este pozitivă.
Ca exemplu care ilustrează utilizarea comenzilor grupului IF, să dăm definiția comenzii limbajului de bază ABS, care calculează modulul din partea superioară a stivei.
: ABS [X] C IF-NEG [| X |];
Comenzile BR-, BR0 și BR + corespund instrucțiunii IF-THEN-ELSE, care vă indică să alegeți una dintre cele două proceduri numite după ele. Dacă semnul elementului ieșit din stivă coincide cu cel din desemnarea comenzii, atunci procedura numită prima este executată, iar dacă nu se potrivește, atunci se execută a doua procedură. De exemplu, instrucțiunea BR0 P0 P1 indică executarea procedurii P0 în cazul în care elementul ieșit din stivă este egal cu zero, iar dacă această condiție nu este îndeplinită, atunci executați procedura P1.
Comenzile luate în considerare vă permit să programați economic execuția procedurii în funcție de condițiile date. Cele mai frecvente condiții de forma x<0, x=0, x>0 sunt implementate direct de echipele grupului IF. Conditii x<=0, x<>0, x> = 0 sunt programate cu comenzile BR-, BR0, BR + folosind o operație NOP goală ca primă procedură. De exemplu, dacă x<=0 then P соответствует команда BR+ NOP P. Примером использования команд группы BR может служить следующая реализация команды базового языка NOT, заменяющей нулевое значение вершины стека единицей, а ненулевое - нулем.
: NU [x] BR0 1 0;
Ramificarea programului se face adesea după comenzi de comparare (<, =, >) care produc o valoare logică de 1 sau 0, în funcție de rezultatul comparării celor două numere. Comanda limbajului de bază MAX, de exemplu, poate fi programată după cum urmează:
: MAX C2 C2< IF+ E2 D ;
Grupul de comenzi de ramificare include și comanda de selecție BR, scrisă sub forma:
BR A1 P1 A2 P2 ... AK PK ... AN PN ELSE P0
La executarea acestei instrucțiuni, procesorul execută mai întâi procedura A1 și compară valoarea pe care a introdus-o pe stivă cu valoarea de sub ea în partea de sus a stivei. Dacă valorile se potrivesc, atunci cele două elemente de sus sunt eliminate din stivă și se execută procedura P1 alocată indicatorului A1, după care se face trecerea la comanda după comanda BR (adică, în înregistrarea de mai sus a programul care urmează cuvântului P0 din text). Dacă valorile comparate nu se potrivesc, atunci un element superior este eliminat din stivă (adică rezultatul A1) și aceleași acțiuni sunt efectuate cu perechea A2 P2, atunci, dacă potrivirea nu a funcționat, atunci cu perechea A3 P3 etc. până la AN PN inclusiv. În cazul în care niciuna dintre încercări nu a dat o potrivire, se execută procedura P0 numită după cuvântul ELSE. De obicei, constantele numerice acționează ca proceduri pointer, de exemplu:
[x] C BR 5 NEG -3 ABS 0 NU ALTE T0 [y]
Ca urmare a executării acestei linii în vârful stivei, se va obține valoarea y = -5 dacă x = 5; y = 3 dacă x = -3; y = 1 dacă x = 0 și y = 0 în caz contrar.
În general, o procedură pointer poate fi nu numai o constantă numerică, ci și o variabilă sau orice altă procedură care satisface o cerință simplă: nu scoate nimic din stivă și împinge o valoare în stivă.
Ca o ilustrare a modului în care sunt utilizate operațiile de execuție condiționată, modificăm procedura TIME în secțiunea anterioară, astfel încât contorul să se oprească atunci când este specificată condiția:
: TIME [t] 1- C IF + TIME;
Acum această rutină TIME se numește singură atunci când partea de sus a stivei este pozitivă. Contorul va fi declanșat de exact N ori dacă la începutul primei execuții a TIME vârful conține un număr pozitiv N. De exemplu, pentru a obține 7 declanșatori, trebuie să setați
7 TIMP<ВК>
Deoarece IF + din definiția TIME, ca orice operație condiționată, scoate elementul testat din stivă, iar acest element este necesar pentru operațiunile ulterioare, trebuie duplicat prin plasarea operației C (Copiere) înaintea IF +.
Recursiunea nu este mijlocul principal de a executa o procedură de mai multe ori. Pentru programarea buclelor în limbajul PARADISE există comenzi RP (Repeat) și DO (Do - do, execute).
Comanda RP W indică executarea procedurii W din nou și din nou, de un număr nelimitat de ori. Pentru ca repetițiile să se oprească, corpul procedurii W trebuie să conțină o operație EX (Exit) care să fie efectuată în condiția dată. Operația EX trece la execuția procedurii care urmează procedura repetată care conține această operație EX în textul programului. Deci, contorul implementat mai sus ca procedură recursivă TIME poate fi programat ca o repetare a procedurii W, care este definită astfel:
: W [t] 1-C IF0 EX;
Pentru ca contorul să funcționeze de 25 de ori, trebuie să executați linia
Alături de operația EX, care este folosită în comenzile de execuție condiționată, există și operațiuni de ieșire condiționată EX-, EX0, EX +, care produc același efect ca și comenzile IF-EX, IF0 EX, IF + EX, adică ele consuma varful un element care isi testeaza semnul si efectueaza o iesire daca semnul se potriveste cu cel indicat in denumirea operatiei. Operațiile EX, EX-, EX0, EX + pot fi utilizate nu neapărat în corpul procedurii repetate în sine (în cazul nostru, W), dar și în procedurile la care se referă.
Ca exemplu, luați în considerare problema găsirii celui mai mare divizor comun al două numere naturale prin metoda lui Euclid. Esența metodei este că este necesar să se scadă numărul mai mic din numărul mai mare până când numerele devin egale între ele. Când se ajunge la egalitate, se va găsi cel mai mare divizor comun.
Programarea va fi realizată prin metoda dezvoltării de sus în jos. În primul rând, definim procedura GCD, care fixează schema generală a algoritmului. Parametrii acestei proceduri sunt două numere M și N de pe stivă, pentru care se găsește cel mai mare divizor comun. În corpul procedurii GCD, trebuie specificat un proces ciclic de conversie a valorilor din stivă. Ca rezultat al acestui proces, două numere egale ar trebui să rămână pe stivă - oricare dintre ele poate fi luat drept cel mai mare divizor comun. Având în vedere aceste considerații, procedura GCD poate fi definită după cum urmează.
: GCD RP STEP [nod (M, N), nod (M, N)] D [nod (M, N)];
Acum este necesar să programați un pas al procesului iterativ, adică. definiți procedura STEP. Parametrii acestuia sunt două numere de pe stivă. Trebuie să comparați aceste numere și să părăsiți bucla dacă sunt egale, în caz contrar, scădeți cel mai mic din cel mai mare. Acest lucru se poate face, de exemplu, astfel:
: PAS C2 C2 - BRS NOP EX E2 C2 -;
Acum nu mai există proceduri nedefinite în program și puteți începe să le verificați. Verificarea trebuie efectuată de jos în sus, adică mai întâi trebuie să vă asigurați că procedura STEP funcționează corect și numai apoi - GCD.
Operația DO în limbajul de bază face ca procedura numită după ea să fie repetată de N ori, unde N este numărul conținut în partea de sus a stivei în momentul în care DO este executat. De exemplu, pentru ca procedura P să fie executată de 8 ori, trebuie să specificați
8 DO P
Dacă corpul procedurii P conține cel puțin o operație de ieșire și condiția pentru executarea acesteia este îndeplinită înainte de a se produce numărul specificat de repetări, atunci repetările vor fi încheiate prin ieșirea din procedură, așa cum se face în cazul Operațiunea RP. De exemplu, dacă DO repetă procedura W descrisă mai sus și are IF0 EX în definiția sa, scrierea [T] 30 DO W va provoca 30 de repetări ale lui W dacă T> = 30. Daca 0 Dacă în momentul executării operațiunii DO există o valoare zero sau negativă în vârful stivei, atunci procedura care urmează DO nu va fi executată nici măcar o dată. Pentru a ilustra utilizarea operației DO, definim o rutină NUM care numără numărul de biți diferit de zero din cuvântul de 32 de biți x specificat în partea de sus a stivei. Puneți contorul numărului de unități din sub-stiva. Numărarea celor va consta în repetarea de 32 de ori a procedurii NUMI, în care vom examina un bit al cuvântului x. La ieșirea din buclă, numărul necesar trebuie să fie în sub-stiva. : NUM [x] 0 E2 32 DO NUMI D [N]; Pentru a număra biții non-zero, vom folosi faptul că cel din bitul cel mai semnificativ (al 31-lea) al cuvântului servește ca semn al unui număr negativ. Dacă cuvântul studiat este negativ, adăugați unul la N. La sfârșitul procedurii NUMI, trebuie să mutați cuvântul studiat cu o cifră la stânga. : NUMI C IF-N + SHL; Implementarea procedurii N + este destul de simplă: trebuie să adăugați unul la sub-stratul stivei fără a modifica vârfurile. : N + E2 1+ E2; Procedurile repetate pot conține operațiuni RP și DO în corpurile lor, ceea ce duce la apariția buclelor imbricate, iar orice adâncime de imbricare este permisă. În acest caz, există o operație EXT pentru ieșirea din bucla imbricată care indică adâncimea de imbricare în partea de sus a stivei. De exemplu, ieșirea din două bucle imbricate poate fi setată astfel: Trebuie avut în vedere faptul că utilizarea comenzii EXT necesită o atenție suplimentară, deoarece atunci când programul este modificat, adâncimea de imbricare a buclelor se poate modifica și constanta corespunzătoare înainte de EXT va trebui modificată. Stiva de operanzi este principalul, dar nu singurul, mecanism de manipulare a datelor din PRSP. Este, de asemenea, posibil, împreună cu definițiile procedurilor, să se declare elemente și colecții standard organizate de elemente (așa-numitele structuri) de date, care sunt apoi disponibile pentru utilizare după numele lor. Prin implementarea declarațiilor de date, procesorul își rezervă memoria necesară stocării acestora și asigură mecanismele necesare pentru accesarea acestei memorie. Limbajul de bază al DSPN include un număr de cuvinte directive discutate mai jos pentru declararea variabilelor și matricelor. Pentru a extinde limbajul sistemului, în el pot fi introduse alte cuvinte de acest fel și, în consecință, alte elemente și structuri de date. Cuvântul VAR declară o variabilă numerică de 16 biți. De exemplu, intrarea declară o variabilă X, adică îi spune procesorului că numele X este numele unei variabile. Procesorul asociază cu acest nume o locație de memorie de 16 biți în care va fi stocată valoarea acestei variabile. Instrucțiunea de atribuire a variabilei X la valoarea conținută în partea de sus a stivei de operanzi are forma Când execută această comandă, procesorul scoate elementul de sus din stivă și își scrie valoarea în locația alocată pentru variabila X. O comandă constând doar dintr-un nume de variabilă fără literă! Determină ca valoarea acestei variabile să fie împinsă în stivă, iar împingerea se face prin copierea conținutului locației de memorie corespunzătoare, adică valoarea variabilei rămâne neschimbată . Astfel, orice intrare în program a numelui variabilei X, cu excepția cazului în care este precedată imediat de un cuvânt care prescrie o acțiune diferită, va împinge valoarea curentă a acestei variabile în stivă, la fel ca numerele direct specificate (literale numerice) sunt împinse pe stivă. Ca exemplu, să dăm o altă versiune a procedurii GCD discutate mai sus în care sunt utilizate două variabile de lucru. : DOAMNE! X! Y RP PASUL X [GCD]; : PASUL X Y = EX + X Y BR + X-Y Y-X; : X-Y X Y -! X; : Y-X Y X -! Y; După cum puteți vedea, programul a devenit ceva mai lung, dar claritatea sa a crescut. Cuvântul VCTR declară o matrice unidimensională (vector) de celule de 16 biți, iar numărul celui mai semnificativ element al acestei matrice este dat de valoarea vârfului. De exemplu, ca urmare a scrisului 9 VCTR ROW Procesorul rezervă 10 cuvinte de memorie de 16 biți adresabile secvenţial, formând un vector ROW (0:9). Mai întâi, numărul 9 este împins pe stivă, iar apoi este executată procedura VCTR, care utilizează elementul superior al stivei pentru a determina lungimea vectorului RÂND de creat. Împingeți valoarea j-lea element al vectorului ROW, 0 în stivă<=j<=9, задается командой [j] RÂND Folosind numărul elementului de pe stivă ca parametru, numele vectorului ROW face ca acest număr să fie înlocuit cu valoarea elementului corespunzător. Dacă cuvântul! Este imediat înaintea numelui vectorului RÂND, atunci valoarea căii secundare este atribuită elementului acestui vector indicat de vârf, iar adâncimea stivei scade cu 2. De exemplu, puteți zero Al 5-lea element al vectorului ROW, după cum urmează: Există, de asemenea, posibilitatea de a crea vectori constanți, adică. vectori de numere de 16 biți, ale căror valori au fost determinate în timpul declarației sale și nu vor fi modificate în viitor. Deci, un vector de constante de 16 biți VC de lungime L + 1 este declarat folosind cuvântul CNST sub forma: CNST VC k0 k1 ... kL; unde k0, k1, ... kL sunt comenzi care împing o valoare în stivă. Cel mai adesea acestea sunt doar literale numerice, dar pot exista și nume de variabile, proceduri, precum și comenzi formate din perechi de cuvinte, cum ar fi, de exemplu, comanda pentru setarea adresei variabilei „X” discutată mai jos. la componentele vectorilor obișnuiți. De exemplu: O matrice multidimensională de cuvinte de 16 biți este declarată folosind cuvântul ARR, precedat de valorile maxime ale indexului pentru fiecare dimensiune și numărul de dimensiuni. De exemplu, o matrice 3D TIR (0: 8.0: 2.0: 24) este declarată astfel: Numărul 3 imediat înainte de ARR denotă dimensiunea tabloului declarat. Împingerea unui element de matrice pe stivă se realizează prin specificarea indexului acestui element urmat de numele matricei. De exemplu, comanda de a împinge elementul TIR (0,2,2) pe stivă este exprimată ca În consecință, atribuirea acestui element a valorii curente a vârfului stivei este setată de comandă Toate exemplele luate în considerare au ilustrat crearea de structuri din cuvinte de 16 biți. Cu toate acestea, limbajul vă permite, de asemenea, să definiți structuri de cuvinte pe 32 de biți și octeți de 8 biți. Pentru a face acest lucru, prefixul LONG sau BYTE este plasat înaintea cuvântului care definește structura, respectiv. De exemplu, 5 BYTE VCTR X - definirea unui vector cu 6 componente de octeți X; BYTE CNST Y 65 66 67; - definirea unui vector-constant Y cu 3 componente octet; 10 20 2 LONG ARR MTRX - definirea unei matrice de cuvinte lungi MTRX (0: 10,0: 20). Citirea elementelor structurilor de cuvinte și octeți se face în același mod ca și în cazul structurilor de cuvinte pe 16 biți. Dacă lungimea elementului este mai mică de 32 de biți, valoarea extrasă este plasată în cuvântul sau octetul cel mai puțin semnificativ din partea de sus a stivei, iar partea superioară a vârfului este zero. Cuvântul sau octetul cel mai puțin semnificativ al cuvântului lung de 32 de biți din stivă este de asemenea luat ca valoare atribuită unui element al unui cuvânt sau al unei structuri de octeți. Deși formatul de cuvânt pe 16 biți este utilizat în definirea datelor în mod implicit, are și o notație WORD. Este recomandabil să folosiți acest prefix atunci când programul ar trebui să fie transferat pe alte mașini, unde este implementat și DSSP și implicit poate fi diferit. Structurile de date pe octeți sunt cel mai adesea folosite pentru a stoca și procesa informații textuale. Acest lucru se datorează faptului că un octet este alocat în memoria computerului pentru a codifica un caracter. Pentru a seta codurile de litere în limba PARADISE există o construcție #l, unde l este orice literă disponibilă pe tastatura computerului. Procesorul DSPP percepe această construcție ca o comandă de a împinge litera l în stivă. De exemplu: Această construcție efectuează aceleași acțiuni ca un literal numeric egal cu codul literei specificate, dar utilizarea sa este mai de preferat, deoarece, în primul rând, vă eliberează de necesitatea de a memora coduri și, în al doilea rând, face programele mai ușor de înțeles. În special, se poate da următoarea definiție a unui vector constant Y: BYTE CNST Y #A #B #C; Este adesea convenabil să folosiți notația simbolică a unei constante numerice într-un program. Cuvântul de definiție VALUE este disponibil pentru a oferi această capacitate: Această comandă scoate elementul de sus din stivă și formează cuvântul cu numele imediat după VALOARE. Folosirea acestui cuvânt echivalează cu utilizarea unei constante numerice. De exemplu: Mijloacele luate în considerare oferă posibilitatea de a numi date și de a manipula datele indiferent de sistemul de adrese al computerului. Dar limbajul de bază include și mijloace pentru manipularea adreselor elementelor de memorie. Adresa unei variabile sau a unui element al matricei X este împinsă în stivă de către comandă În cazul unui element de matrice, această comandă este precedată de valoarea indexului (indexurilor). Comanda limba gazdă @ înlocuiește adresa unui cuvânt cu memorie lungă din partea de sus a stivei cu valoarea care conține acel cuvânt. De exemplu, valoarea lui Y poate fi împinsă în stivă executând următoarea linie: @B înlocuiește adresa cu valoarea octetului corespunzător, presupunând zero octeți mari, iar @L înlocuiește adresa cu un cuvânt de 32 de biți. Există, de asemenea, comenzi pentru scrierea valorilor în memorie. Comanda! T scrie la adresa apărută din partea de sus a stivei subvaloarea de 16 biți. Comanda! TB determină o scriere similară a octetului de ordin inferior al sub-octetului cu octetul adresat de partea de sus, iar! TL scrie cuvântul de 32 de biți al sub-octetului în cuvântul adresat de partea de sus. De exemplu, puteți atribui valoarea 15 celui de-al cincilea element al vectorului octet BV (0:5) cu următoarele comenzi: 15 5 "BV! TB Necesitatea de a lucra cu memorie la adrese fizice apare de obicei atunci când se creează programe care depind de arhitectura unui anumit computer, de exemplu, când se creează drivere de intrare/ieșire. Pentru a obține o mai mare eficiență și compactitate a programelor, în limbajul PARADISE au fost introduse următoarele operații: 0 <имя переменной>- reseta variabila; 1 <имя переменной>- atribui o unitate unei variabile; 1- <имя переменной>- scade valoarea variabilei cu unu; 1+ <имя переменной>- creste cu unu valoarea variabilei; !- <имя переменной>- scade valoarea varfului stivei din variabila; !+ <имя переменной>- adăugați valoarea vârfului stivei la variabilă. Fiecare dintre aceste operații este ușor de programat folosind comenzi de citire și scriere pentru variabile. De exemplu, 0 X este echivalent cu 0! X 1+ X este echivalent cu X 1+! X X este echivalent cu X E2 -! X Utilizarea acestor operațiuni va crește eficiența și vizibilitatea programelor. În practică, deseori doriți să atribuiți o singură valoare tuturor elementelor unui tablou. Pentru aceasta, există o operațiune în limba PARADIS !!!<имя массива>... Acțiunea sa este de a atribui valoarea vârfului stivei tuturor componentelor matricei specificate. Operațiune!!! aplicabil matricelor cu elemente de orice format. Exemplu de utilizare: un cod de caractere de spațiu este scris în toate componentele matricei de octeți BUF. Este adesea necesar să obțineți informații în program despre structura de date din spatele numelui. O pereche de comenzi SIZE? - dați formatul elementului de date: 1, 2 sau 4 octeți și DIM? - dați numărul de elemente de date din structură. De exemplu, dacă datele sunt declarate 3 4 2 ARR LUNG Z apoi aplicate acestora, aceste comenzi vor da următorul rezultat (numere zecimale): MĂRIMEA? DIMENSIUNEA X? DIMENSIUNEA Y? Z DIM? X DIM? Y DIM? Z Setul de instrucțiuni al procesorului DSPP include, ca adaos, patru comenzi care vă permit să citiți și să scrieți biți individuali din celulele de memorie ale computerului. Acestea sunt comenzile @BI,! BI,! BI0,! BI1. Parametrii fiecăruia dintre ei sunt adresa cuvântului de memorie situat pe stivă și numărul de biți din acest cuvânt (reamintim că biții sunt numerotați de la dreapta la stânga, începând de la zero). Comanda! BI presupune, de asemenea, că există un bit pe stivă și o valoare de scris. Comanda @BI înlocuiește parametrii specificați cu valoarea bitului selectat (0 sau 1), comenzile! BI0 și! BI1 setează bitul selectat la 0 și, respectiv, 1, eliminând parametrii acestora din stivă, iar! BI comanda setează bitul selectat la valoarea celui mai puțin semnificativ al celui de-al treilea element al stivei și elimină toți cei trei parametrii săi din stivă. De exemplu, dacă valoarea variabilei X este un număr binar 101101, atunci rezultatele operațiilor enumerate vor fi următoarele: „X [adr.X] 3 @BI - al treilea bit al lui X, 0” X 3! BI - X este egal cu 100101, „X [addr.X] 0! BI0 - X este egal cu 100100, „X [adr.X] 1! BI1 - X este 100110. În limbajul PARADISE există și facilități pentru lucrul cu șiruri de octeți localizați în memorie. Pentru a seta un șir de octeți, doi parametri sunt împinși în stivă: adresa de început a șirului (adică adresa primului său octet) și lungimea șirului (numărul de octeți din acesta). Comanda !!! MB este folosită pentru a atribui toți octeții unui șir unei valori (setate pe stivă). Acesta consumă trei parametri din stivă:, unde b este valoarea atribuită, a și l sunt adresa de pornire și respectiv lungimea șirului de octeți. Să presupunem, de exemplu, că trebuie să zero elemente de la al 3-lea la al 10-lea octet TXT (0:20). Pentru a face acest lucru, puteți rula următoarea linie: 0 3 "TXT 8 !!! MB ca urmare, opt elemente consecutive ale matricei specificate, începând cu a 3-a, vor primi valoarea 0. O comandă similară!!!MW are scopul de a umple o secvență de cuvinte de 16 biți cu aceeași valoare (numărul de cuvinte este indicat în partea de sus a stivei), iar comanda! !! M - pentru a completa o secvență de cuvinte lungi. Comanda! SB transferă șiruri de octeți. Parametrii săi sunt:, unde a1 și l sunt adresa de pornire și lungimea șirului transferat, a2 este adresa de început a șirului către care se efectuează transferul. Ca rezultat al executării comenzii! SB, un șir de octeți de lungime l va fi localizat în memorie de la adresa a2, care este o copie exactă a șirului situat la adresa a1 înainte de efectuarea transferului. Șirul sursă și șirul destinație se pot suprapune. De exemplu, să presupunem că doriți să mutați elementele matricei de octeți M (0:10) după cum urmează: M (10): = M (9), M (9): = M (8), ..., M (1): = M (0). Pentru a face acest lucru, puteți utiliza comanda! SB: 0 "M 10 C2 1+! SB ca urmare, un șir de 10 octeți va deplasa un octet către creșterea adreselor de memorie. Comanda! SB este convenabilă pentru lucrul cu șiruri de caractere (reamintim că fiecare caracter este codificat într-un octet). Permite, de exemplu, să atribuiți valoarea unui șir literal specificat explicit unei matrice de octeți. Pentru a specifica un astfel de șir, utilizați un text literal, adică o succesiune de caractere cuprinse între ghilimele, de exemplu „TEXT LITERAL”. Această construcție, când este întâlnită într-un program, face ca adresa de început și lungimea șirului de octeți care conține textul cuprins între ghilimele să fie împins în stivă. Acești parametri pot fi apoi utilizați de comanda! SB. De exemplu, fragmentul „TABLE” 0 „TN! SB va face ca literalul TABLE să fie trimis la matricea TN. Comanda SRCHB caută un șir pentru un octet specificat. Parametri:, unde b este octetul, a cărui primă apariție trebuie găsită, a și n specifică adresa începutului și respectiv lungimea șirului de căutare. Dacă n> 0, atunci căutarea se efectuează de la adresa a la adresa a + n-1 (în direcția de creștere a adreselor), dacă n<0, то поиск ведется с адреса a до адреса a+n+1 (в сторону убывания адресов). В результате выполнения этой команды в стеке оказывается значение d, равное смещению относительно адреса a до первого вхождения байта b. Если такое вхождение не обнаружено, то d=n. Примеры: #T „TEXT” SRCHB #A „TEXT” SRCHB #E „TEXT” [# E, a, 4] 1- + -4 [# E, a + 3, -4] SRCHB [-2] Terminând luarea în considerare a mijloacelor de lucru cu date, să ne oprim asupra problemei stocării datelor în memoria externă a unui computer, adică. pe discuri magnetice. În limbajul PARADISE există o comandă SAVE<имя файла>pentru a salva o copie a memoriei principale a sistemului pe disc împreună cu obiectele definite de utilizator. În acest caz, zonele de memorie alocate pentru date de către operațiunile VAR, VCTR, ARR nu sunt afișate pe disc. Ca urmare, la pornirea unui sistem salvat de pe disc, valorile datelor specificate nu sunt definite (acestea trebuie determinate în timpul execuției programului). În cele mai multe cazuri, acest lucru este justificat, deoarece nu este nevoie să cheltuiți memoria discului pentru a stoca variabile de lucru, buffer-uri etc. Cu toate acestea, există date, ale căror valori trebuie determinate imediat după ce sistemul este pornit de pe disc. Un exemplu este o variabilă care stochează viteza schimbului de date cu un dispozitiv extern. Când treceți la un alt curs de schimb, este suficient să modificați valoarea acestei variabile fără a face nicio corecție în program. O indicație pentru procesor că valorile elementelor unei structuri de date ar trebui să fie scoase pe disc de comanda SAVE este prefixul FIX plasat înaintea definiției structurii, de exemplu FIX VAR SPEED 20 FIX BYTE VCTR TABL Lucrul cu structuri de date definite în acest mod nu este diferit de lucrul cu structuri definite în mod obișnuit. În limbajul PARADISE există un grup mic de comenzi menite să controleze procesorul DSPP, sau mai degrabă emulatorul procesorului DSPP. Comanda RESTART determină o repornire a procesorului. În acest caz, stiva este golită, mesajul este emis Versiunea DSSP XX.XX.XX XXXXXW gratuit iar procesorul intră în modul de așteptare pentru intrarea comenzii. Această comandă este utilă la depanarea programelor. De asemenea, se execută atunci când apare o condiție de eroare: indexul depășește limitele matricei, memoria liberă este epuizată etc. Comanda \G este folosită pentru a continua execuția programului după oprirea la un cuvânt nedefinit. Dacă, în timpul executării unei proceduri, procesorul întâlnește o referire la un cuvânt nedefinit, emite un mesaj: opreste nu stiu<слово> . unde punctul este invitația procesorului DSPP, care semnalează că procesorul este într-o stare de oprire pe un cuvânt nedefinit. În acest mod, puteți executa orice comenzi de procesor, la fel ca în modul normal, când asteriscul este promptul. Există două modalități de a ieși din acest mod - fie prin executarea comenzii \G (apoi procesorul va continua să execute procedura întreruptă, sărind cuvantul nedefinit), fie prin comanda RESTART. EXEC instruiește procesorul să execute o procedură a cărei adresă se află în partea de sus a stivei. Pentru a obține adresa procedurii, utilizați comanda „” (două apostrofe) urmată de numele procedurii. De exemplu, ca rezultat al comenzii adresa procedurii ABS va fi împinsă pe stivă. Aceste comenzi vă permit să treceți o procedură ca parametru unei alte proceduri. Operația SAVE deja menționată aparține grupului de comenzi de control al procesorului.<имя файла>, prescriind salvarea unei copii a sistemului pe disc, precum și comenzile care determină sursa de introducere a informațiilor text furnizate la intrarea procesorului. Sursa principală este tastatura de afișare. Comanda LOAD<имя файла>comută intrarea la un fișier disc cu numele specificat. Comanda PF - prescrie introducerea comenzilor din buffer-ul editorului de text. Comanda TEXEC transmite un șir de text la intrarea procesorului, ai cărui parametri sunt setați pe stivă. La executarea comenzilor conținute în sursele specificate, intrarea comută automat pe tastatura de afișare. Fluxul de instrucțiuni de intrare perceput de procesor poate conține, în special, instrucțiuni pentru definirea procedurilor și a datelor care provoacă compilarea în reprezentarea internă și stocarea corpului procedurii sau alocarea de memorie pentru datele specificate, precum și introducerea numelui compilatului. procedura sau structura de date în dicționarul DSPP. Dicționarul stabilește o corespondență între nume externe (utilizate în textul programului) și adresele obiectelor corespunzătoare acestor nume în reprezentarea internă. Atunci când prelucrează definiția unei proceduri sau o descriere a unei date numite, procesorul alcătuiește un dicționar, formând în el o nouă intrare de dicționar care conține numele (mai precis, primele 7 litere ale numelui) și adresa procedurii. corp sau descriptor de date care este mapat cu acest nume. În programarea de sus în jos, corpurile de procedură pot conține referințe la obiecte care nu sunt încă definite. În acest caz, intrările de dicționar (anteturile) sunt formate în dicționar, marcate cu un semn de ambiguitate. Comanda UNDEF este utilizată pentru a afișa toate numele nedefinite pe ecranul de afișare. În cursul construirii dicționarului, este posibil să se formeze subdicționare - colecții denumite de intrări de dicționar. Un subdicționar combină de obicei proceduri și structuri de date legate de o singură sarcină. Pentru a evita confuzia între numele subdicționarelor și alte obiecte de program, numele unui subdicționar trebuie să înceapă cu caracterul $. Accesul la subdicționare pentru extinderea sau utilizarea lor poate fi deschis și închis cu comenzi speciale, care includ următoarele (numele $ v înseamnă orice subdicționar valid). GROW $ v - măriți subdicționarul $ v, adică până când este prescris altfel, introduceți numele tuturor procedurilor și datelor compilate în subdicționarul $ v; USE $ v - deschide pentru utilizare (pentru a căuta nume în el) subdicționarul $ v; SHUT $ v - închide capacitatea de a folosi subdicționarul $ v; ONLY $ v - face doar subdicționarul $ v disponibil pentru utilizare; ANULARE - anulați NUMAI ultimul. Există și comanda? $, care tipărește pe afișaj numele tuturor subdicționarelor din starea lor - subdicționarul este deschis sau închis pentru căutare. Dicționarul, al cărui nume este tipărit în partea de sus, este întotdeauna incrementat. Procedurile de bază ale PRSP alcătuiesc un subdicționar numit $ PRIME, deschis pentru utilizare și extindere în mod implicit, adică dacă nu a existat nicio comandă care să prevadă extinderea unui alt subdicționar. Să presupunem, de exemplu, operația? $ A tipărit următoarea stare a subdicționarelor. $ PRG deschis $ PRIME deschis $ EDIT închis $ PRIME deschis SISTEM închis Aceasta înseamnă că $ PRG este în prezent deschis pentru extensie și utilizare, $ PRIME este doar pentru utilizare, iar $ EDIT și SYSTEM nu sunt disponibile. Rețineți că un subdicționar poate consta din mai multe secțiuni cu aceleași nume. Există comenzi pentru ștergerea unui anumit set de intrări din dicționar și, poate, a obiectelor interne aferente. Astfel, comanda FORGET $ v șterge toate numele introduse în dicționar (nu doar în subdicționarul $ v) după ultima execuție a comenzii GROW $ v împreună cu obiectele indicate prin aceste nume și anulează extinderea subdicționarul $ v pe care l-a setat. Comanda PROGRAM $ v face același lucru ca și comenzile secvențiale FORGET $ v GROW $ v. Prezența unei astfel de comenzi la începutul oricărui program duce la faptul că atunci când programul este recompilat, vechea lui copie va fi ștearsă și se va forma un dicționar pentru a stoca obiectele noii copii a programului. De exemplu, efectuând operația FORGET $ PRIME pe un dicționar, a cărui stare a fost afișată mai sus, obținem o nouă stare: $ EDIT închis $ PRIME deschis SISTEM închis În timpul executării comenzii FORGET, sunt afișate numele secțiunilor de șterse. Rețineți că numele subdicționarului SISTEM nu începe cu $. Acest lucru este permis, dar duce la faptul că aplicarea comenzilor FORGET și RPOGRAM la acest subdicționar nu provoacă nicio acțiune (subdicționarul SYSTEM nu există pentru ele, așa cum ar fi). Datorită faptului că, în programul finalizat pentru majoritatea covârșitoare a procedurilor, nu este necesară o contestație prin nume extern, este posibil să le ștergeți numele din dicționar, păstrând în același timp obiectele interne asociate acestora. Comanda CLEAR $ v elimină toate numele din toate secțiunile subdicționarului $ v, cu excepția celor precedate de pre-prefixul :: (două două puncte) în textul programului (când le definiți). De exemplu, ca urmare a executării de către procesor a următorului fragment de program: ::: X + Y! + X; CLEAR $ EXAM doar numele X și X + vor rămâne în subdicționarul $ EXAM, intrarea din dicționar Y va fi eliminată (deși variabila corespunzătoare cuvântului Y în reprezentarea internă va rămâne). Principalul mijloc de interacțiune între utilizator și DSPP este terminalul, care, de regulă, este un afișaj cu raze catodice cu o tastatură. Terminalul este utilizat pentru introducerea inițială, editarea și depanarea programelor, pregătirea datelor și managementul întregului sistem. Programele și datele, precum și PAL în sine, sunt salvate ca fișiere pe discuri și pot fi tipărite pe o imprimantă. Următoarele instrumente sunt disponibile pentru controlul I/O în setul de proceduri de bază ale PRSP. Programarea funcționării terminalului este asigurată de comenzi pentru introducerea și ieșirea numerelor, litere individuale și secvențe de litere (linii), precum și unele comenzi suplimentare. Comanda TIB (Terminal Input Byte) inițiază o buclă care așteaptă apăsarea unei taste pe tastatura terminalului. Când o tastă este apăsată, codul de 8 biți al literei corespunzătoare este împins în stivă ca octet cel mai puțin semnificativ al vârfului, cei mai semnificativi 3 octeți conținând zerouri. O copie a literei introduse în acest fel este afișată pe afișaj. Există, de asemenea, o comandă TRB (Terminal Read Byte), care diferă de TIB prin faptul că împingerea codului literei introduse pe stivă nu este însoțită de afișarea acestei litere pe afișaj. Comanda TIN (Număr de intrare terminal) inițiază un ciclu de intrare în stivă și afișarea numărului tastat de la tastatură pe afișaj. Numărul introdus trebuie să fie o secvență de numere, care poate începe cu semnul minus și se poate termina Fiecare comandă TIN introduce un număr. Dacă este necesar să introduceți o succesiune de numere pe o singură linie, acestea trebuie separate prin apăsarea tastei O secvență care conține n caractere tastate de la tastatură este introdusă în memoria computerului sub formă de n octeți aflați la adrese în creștere secvențială, începând de la adresa a, folosind comanda TIS (Terminal Input String), înaintea căreia adresa a și numărul de literele n sunt împinse pe stivă... De exemplu, să fie declarat un vector octet X de lungime suficientă. Trebuie să introduceți 9 caractere, atribuindu-le valorile elementelor acestui vector, începând de la elementul zero: În mod similar, comanda TOS setează rezultatul unei secvențe de n caractere-octeți cu adresa de pornire a: Ieșirea către terminal a elementelor text incluse direct în program este asigurată de construcție ."<текст>" De exemplu, pentru ca atunci când se execută un anumit fragment al programului, pe display să apară textul ENTER VARIANT NUMBER, fragmentul trebuie să conțină mențiunea „INTRODUCEȚI NUMĂRUL VARIANTEI”. Comanda TON (Număr de ieșire terminal) afișează numărul scos din sub-stiva, iar lungimea câmpului de ieșire trebuie specificată în partea de sus. Numărul afișat este aliniat la marginea dreaptă a câmpului, pozițiile libere din stânga sunt umplute cu spații, iar dacă lungimea numărului depășește lungimea specificată a câmpului, partea stângă este tăiată. În modul I/O zecimal, numerele negative încep cu semnul minus. Comanda TOB (byte de ieșire terminal) tipărește litera al cărei cod este specificat de octetul inferior din partea superioară a stivei. Adâncimea stivei este redusă cu 1. Există, de asemenea, comenzi care controlează direct cursorul de afișare: CR - săriți la începutul unei noi linii, SP - spațiu, adică mutați o poziție la dreapta. Comanda BELL produce un bip scurt ("clopot"). Uneori, atunci când comunicați cu terminalul, este necesar să verificați dacă tasta a fost deja apăsată și dacă afișajul a finalizat deja comanda anterioară de ieșire. Acest lucru se poate face cu comenzile TTI (Terminal Test Input) și TTO (Terminal Test Output), care lasă indicatorul 1 pe stivă dacă evenimentul specificat a avut loc și 0 în caz contrar. Comenzile de ieșire ale imprimantei sunt similare cu comenzile de ieșire ale terminalului și se bazează pe un mnemonic similar, în care caracterele LP (Imprimantă de linie) fie au înlocuit TO, fie au adăugat ca lider. De exemplu, LPCR - săriți la începutul unei noi linii, LPSP - spațiu, LPN - scoateți un număr din sublinie în câmpul specificat de vârf, LPB - scoateți un caracter, LPS - scoateți un șir de caractere. Există, de asemenea, comanda [N] LPT, care mută capul de imprimare în poziția N a liniei tipărite, și comanda LPFF, care alimentează o coală de hârtie. Pentru a imprima text specificat în mod explicit, este convenabil să utilizați un text literal și comanda LPS, de exemplu: "TABELUL VALORILOR FUNCȚIILOR" LPS La programarea perifericelor, devine necesară gestionarea întreruperilor. În DSPP, această procesare este programată după cum urmează. Programul destinat tratării întreruperilor este o procedură PRSP normală, înainte de definirea căreia există un pre-prefix INT, de exemplu INT: A! 1+ I; Prefixul INT asigură că starea procesorului este salvată în timpul întreruperii și restaurată atunci când întreruperea este procesată. Pentru a lega un program piesă la o anumită întrerupere, utilizați comanda LINK: <адрес вектора>LEGĂTURĂ<имя процедуры>când este executat, un apel la rutina de gestionare a întreruperilor este scris de-a lungul vectorului corespunzător. Comanda LINK poate efectua atât legarea statică a unei proceduri cu o întrerupere, care apare în momentul compilării programului, cât și dinamică, în timpul execuției programului. O întrerupere a procesorului este modul în care sistemul este informat despre un eveniment care a avut loc în lumea exterioară. Evenimentele care necesită procesare imediată pot apărea și în program. Acestea se numesc situații excepționale. Exemple de astfel de situații: împărțirea la zero, eroare de comunicare cu dispozitivul, sfârșitul fișierului de intrare etc. În DSPP, excepțiile sunt capturate folosind întreruperi de comandă. O întrerupere de comandă este o operație numită care apelează o procedură de răspuns și este declarată după cum urmează: CAPCANĂ<имя вызова> <конечная реакция> De exemplu: CAPCANĂ S1 „Situația S1”. În primul caz, procedura X este reacția finală la întreruperea S; în al doilea, când are loc o întrerupere S1, terminalul va primi un mesaj: Situația S1. Programul, în timpul execuției căruia poate apărea întrerupere, își poate seta reacția la acesta folosind comanda de interceptare. DSSP prevede două tipuri de interceptări: ON și EON. Comenzile de interceptare pot fi utilizate numai în cadrul procedurilor și au formatul: PE<имя прерывания> <реакция> EON<имя прерывания> <реакция>De exemplu: : A ... ON S. „Întreruperea S” ...; : A1 ... EON S1 ABC ...; ON și EON stabilesc diferite tipuri de reacții. Dacă o nouă reacție este setată de comanda ON, atunci când apare o întrerupere, se execută o procedură de reacție, după care programul întrerupt continuă să ruleze. Dacă reacția este setată de comanda EON, atunci la început stiva de operanzi își asumă adâncimea pe care a avut-o în momentul execuției EON, atunci reacția este efectuată, iar după finalizarea acesteia se execută procedura în care a fost comanda EON. folosit este imediat terminat. Să ne uităm la câteva exemple. Procedura M introduce caractere de la tastatura terminalului și verifică dacă este o cifră. Dacă caracterul introdus nu este o cifră, întreruperea ND este ridicată. TRAP ND. „Nici o cifră”. : M RP M1; : M1 TRB [B] C # 0< C2 #9 >& 0 IF + ND [B] TOB; Răspunsul final la o întrerupere ND este mesajul: Nu este o cifră. Dacă M este apelat din procedura P1, care are propriul răspuns la întreruperea ND: P1 ON ND PR1 M; : PR1 [B] CR. „Eroare”. D # 0 [# 0]; apoi atunci când este introdus un caracter nedigital, întreruperea ND va fi procesată de programul de reacție PR1 de tip ON, ceea ce va face ca următorul mesaj să fie scos dintr-o nouă linie: Eroare. Litera introdusă va fi înlocuită cu litera 0, după care M va continua să lucreze. Dacă M este apelat din procedura P2: P2 EON ND PR2 M; : PR2 CR. „Eroare. Sfârșitul introducerii”. ; apoi atunci când este introdus un caracter nedigital, întreruperea ND va fi procesată de programul de reacție PR2 de tip EON, ceea ce va face ca următorul mesaj să fie scos dintr-o nouă linie: Eroare. Sfârșitul intrării., Apoi P2 va ieși. Stiva de operanzi va fi apoi goală. Dacă este necesar, o întrerupere poate fi ridicată din nou în programul de reacție, extinzându-l astfel la programele de nivel superior. În acest caz, întreruperea va fi gestionată fie de programul specificat în comanda de interceptare din procedura anexată, fie de reacția finală. De exemplu, dacă modificați PR2 după cum urmează:: PR2 CR "Eroare. Sfârșitul introducerii." ND; atunci mesajul emis către terminal va fi: Eroare. Sfârșitul intrării. Nu un număr. DSPP are mai multe întreruperi de comandă încorporate, a căror reacție poate fi furnizată în programele utilizatorului. Assalam alaykum wa rohmatullahi wa barakatuhu! Wa aleikum salam wa rahmatullahi wa barakatuh! At-Tabarani în al-Awsat, potrivit lui Abu Huraira, relatează: Sheikh al-Albani l-a adus la Silsil ad-da'ifa la numărul 161, spunând: „Acest hadith este fictiv (maudu’). În realitate, nu există un singur hadith de încredere care să explice ce limbă vor vorbi locuitorii Paradisului, de aceea este necesar să taceți și să nu vă afundați în conversații despre această problemă, lăsând cunoștințele despre aceasta în seama lui Allah Atotputernicul și să faceți doar ceea ce va face. duce la săvârșirea acelor fapte care vor beneficia în lumea cealaltă! Limba este un sistem de semne care vă permite să treceți de la semnificația și sensul unui concept la desemnarea acestuia. Omul este o creatură verbală și, spre deosebire de animale, comunică cu propriul soi folosind limbajul. Uneori se vorbește despre „limbajul animalelor”, dar este clar că o astfel de expresie este condiționată - în ceea ce privește bogăția și capacitățile sale, limbajul animalelor nu este asemănător cu oamenii. Îngerii, pe de altă parte, nu au nevoie deloc de o limbă pentru comunicarea lor - este dificil să-i imaginezi vorbind rusă sau engleză. Funcțiile limbajului pot fi diferite - pe lângă transmiterea de informații, ajută la exprimarea sentimentelor și a aprecierilor. Limbajul Bisericii este limbajul rugăciunii, al închinării și al Scripturii. În unele religii, textele sacre există inițial într-o anumită limbă și sunt considerate fundamental intraductibile. Astfel, Coranul musulman a fost compus inițial în arabă. Mai mult, musulmanii cred că așa a fost creată această carte la începutul timpurilor. Cărturarii evrei erau, de asemenea, înclinați către ideea posibilității de a scrie texte sacre numai în ebraică. Nu a fost cazul Scripturii creștine de la început. În secolul al III-lea î.Hr. s-a realizat așa-numita „traducere a celor șaptezeci” – Septuaginta – traducerea Vechiului Testament în greacă. Mai mult, unii cercetători cred că Septuaginta a fost cea care a jucat rolul Sfintei Scripturi în vremurile inter-testamentare. Existența Septuagintei a devenit principalul argument în favoarea traducebilității principiale a Scripturii. Există, totuși, una și mai puternică. Acum se consideră dovedit că Hristos a vorbit apostolilor în aramaică. Dar compilatorii Evangheliilor nu au ezitat să transmită aceste conversații în limba greacă. Acum există o direcție științifică - reconstrucția lingvistică. Compilatorii lor încearcă să înțeleagă cum au sunat aceste dialoguri în original. Dar totuși acesta este subiectul unor studii științifice. Când traduceți o limbă într-o limbă, uneori apar probleme deoarece limbile nu sunt identice din punct de vedere gramatical. Semnificațiile și nuanțele cuvintelor în diferite limbi sunt, de asemenea, diferite. De exemplu, expresia „raiul este un loc cald și răcoros” arată clar că Scriptura a fost creată în țări cu climă caldă, unde „răcorul” este destul de plăcut. În rusă, cu greu ar apărea astfel de asociații. Iar verbul „a se răcori” în sensul „a se odihni”, „a se distra” a ajuns în rusă ca hârtie de calc de la ebraică la greacă. Scriptura a fost adusă strămoșilor noștri într-un mod non-rus. Chiril și Metodiu - grecii din Solunsk - au dezvoltat o nouă limbă scrisă bazată pe limba vorbită a slavilor din Solunsk. În lume, multe popoare folosesc limbi care nu au o limbă scrisă. Atâta timp cât vorbim despre viața de zi cu zi, nu există probleme. Dar, de îndată ce un text religios sau un tratat filozofic trebuie tradus într-o astfel de limbă, limbajul trebuie îmbunătățit, ceea ce a fost făcut de Chiril și Metodie. Dacă presupunem că triburile slave în urmă cu câteva mii de ani era mai ușor să fie de acord între ele decât popoarele slave moderne, atunci vom avea dreptate - limbile erau mai apropiate. Dar asta nu înseamnă că traducerea Scripturii, făcută de Chiril și Metodie, a fost mai de înțeles pentru oamenii din Kiev și Novgorod - limba literară scrisă era diferită. Poate că aceasta este o caracteristică a situației ruse, deoarece limba literară rusă este mai aproape de slavona bisericească decât de dialectul de la Moscova. De altfel, întreaga limbă slavonă bisericească a intrat în limba rusă ca „calm înalt”. De exemplu, chiar și participiile moderne - cum ar fi plânsul, alergarea - sunt formate tocmai după modelul slavonesc bisericesc - în rusă veche va fi „plâns”, „alergare”. Uneori, omologii ruși vechi au renunțat cu totul - „bun” și „bologo” în numele „Bologoye”; „Shelom”, care este doar în epopee, în contrast cu „casca”. În Rusia Antică a existat o situație de diglosie. Acest lucru nu este ca bilingvismul. Diglosia este utilizarea a două limbi în paralel în societate. De exemplu, în secolul al XIX-lea au fost folosite atât rusă, cât și franceză. Franceza era limba înaltei societăți, dar, în principiu, orice text putea fi tradus. În diglosie, limbile nu se suprapun în ceea ce privește utilizarea. Vorbeau în rusă veche, în rusă veche puteau scrie un bilet de uz casnic. Dar s-au rugat în slavonă bisericească. Această situație a existat înainte de Petru, în secolul al XVIII-lea s-a prăbușit treptat. Acum știința și literatura s-ar putea dezvolta în limba rusă, dar în slavona bisericească mai există doar rugăciunile. Traduceți într-un anunț în slavonă bisericească - și va arăta ca o glumă sau o blasfemie. Trăim într-o eră unică. În Rusia țaristă, Biblia putea fi citită în rusă, în Rusia antică, era posibil să o ascultăm în slavonă bisericească. Dar majoritatea oamenilor erau analfabeți sau nu erau suficient de educați pentru a citi și a percepe Scriptura. În vremurile sovietice, toată lumea devenea alfabetizată, dar nu exista un text din Scriptură. Alfabetizarea este încă păstrată și textele sunt disponibile. Pe lângă Scripturile în sine, suntem invitați să mai stăpânim câteva texte slave - de la rugăciuni la slujbe divine. Adevărat, traducerea existentă în rusă este oarecum greu de înțeles. În secolul al XIX-lea, neavând analogi, traducătorii au tradus adesea slavisme în traducere. Deci expresia „Eu sunt păstorul cel bun” a migrat în traducere. Și iată câteva dificultăți. O traducere literală din greacă ar suna: „Sunt un păstor bun”, dar o astfel de traducere este percepută ca fiind slabă. Pe de altă parte, despre sublimul „pastor” este acum perceput de un simplu ascultător mai mult ca un „preot”. Cu toate acestea, trebuie să admitem că o traducere literală în limba rusă a multor vorbe biblice este imposibilă - expresia „prin gura unui copil spune adevărul” - deoarece o vorbă filozofică nu va fi percepută. Dar, în general, percepția textului slav al Bibliei este mai mult împiedicată de o lipsă de înțelegere a sensului, și nu a cuvintelor. O dificultate separată este construcțiile gramaticale. De exemplu, există o serie de îmbunătățiri care provin din greacă. „Iertați păcatele și fărădelegile” înseamnă pur și simplu a ierta toate păcatele. Construcțiile de tipul „Am fost supărat de furie”, „Am iubit cu dragoste” sunt asemănătoare. La traducerea textelor sacre în alte limbi, apar și probleme (deși popoarele în ale căror limbi Scripturile nu au fost încă traduse sunt, probabil, 5℅ din populația lumii). Adică lucrarea pe care Chiril și Metodiu au făcut-o pentru slavi continuă. Chiril și Metodiu nu au fost primii - înainte au existat traduceri în etiopiană, gotică. După Chiril și Metodie, Ștefan din Perm a tradus Scriptura în limba Zyryan. Fiecare traducere este considerată un text sacru? Nu, dar numai în măsura în care este acceptat în comunitățile bisericești. De exemplu, traducerea sinodală ca traducere liturgică nu este interzisă, dar nu este acceptată. Dar este folosit ca atare de protestanți, de exemplu, baptiștii ruși. Există chiar curente moderne ale protestantismului care cred că textul biblic ar trebui să fie la îndemâna tuturor. Sunt publicate și benzi desenate bazate pe teme biblice. Nu există probleme cu textul Noului Testament - sursa lui este cunoscută în greacă. Dar baza traducerii sinodale a Vechiului Testament a fost textul ebraic. Fragmente din traducerea greacă au fost inserate doar atunci când discrepanțele erau fundamentale. În versiunea modernă, ar fi bine să avem două traduceri - atât din textele ebraice masoretice, cât și din greacă. Ar fi convenabil pentru cei care nu cunosc ambele limbi. După cuvântare, protopopului Alexandru i s-au adresat mai multe întrebări: – Ce limbă vorbea Adam? - E greu de spus. Pe de o parte, limba se schimbă în timp ce este în viață. Dar nimeni nu știe dacă aceasta nu a fost o nouă proprietate a limbilor care a apărut după construirea Turnului Babel. Dar, în orice caz, limba lui Adam era probabil diferită de oricare dintre limbile existente, inclusiv ebraica. – Există vreo controversă cu privire la traducerea serviciului în rusă? - Această idee a fost discutată chiar înainte de revoluție și a fost parțial compromisă de renovaționisti. Nu toți au servit în rusă, dar ideea a fost susținută de ei. Traducerea Bibliei în rusă nu a fost ușoară, deși ideea lui Filaret metropolitan că era necesar să o traducă atât din ebraică, cât și din greacă a fost o decizie înțeleaptă. Deși acest lucru nu ne-a oferit traduceri științifice din ambele limbi. Există cazuri individuale de utilizare a limbii ruse - rugăciunea bătrânilor Optina și acatistul „Slavă lui Dumnezeu pentru toate” au fost scrise inițial în limba rusă. Există atât de multe alte traduceri și vor fi atât de multe nuanțe în implementarea lor, încât este mai ușor să rusificăm oarecum textele decât să le traduci. Acest proces se desfășoară spontan de mult timp. Uneori apar incidente: de exemplu, în „Ritul Nunții” dualul este uneori înlocuit în mod neașteptat de plural, iar în acatistele moderne este folosit inconsecvent. – Cum participă Providența Divină la formarea diferitelor limbi? - Limbajul există în afară de voința umană. O persoană poate crea Esperanto, dar limbile naturale există conform propriilor legi. Chiril și Metodie au tradus în slavona bisericească prin inspirație de sus, dar și după modelul care exista până atunci. Prin inspirație de sus, notând Evangheliile în limba greacă, apostolii și-au pus ideea traducerii Evangheliei. Pregătit de Daria Mendeleeva Fotografie de Dmitry Kuzmin ÎNTREBARE:
Assalam alaikum aha! Aici am dat peste acest articol. Daca nu ma insel, ai scris invers. Dacă nu este dificil, poți comenta din nou acest articol. musulman. Araba este limba Coranului. El a fost alesul dintre toate limbile lumii și are proprietăți extraordinare. Această limbă este și limba profetului Muhammad (pacea și binecuvântările lui Allah fie asupra lui). Această limbă este bogată și niciuna dintre limbile lumii nu poate concura cu ea. El are o influență spirituală și fizică asupra vorbitorului acestei limbi. Anterior, arabii organizau concursuri de poezie, dar când Profetul (s.a.s.) a primit Apocalipsa, arabii au fost atât de uimiți de o expresivitate atât de minunată a limbii și chiar unii au crezut că Coranul a avut un efect magic asupra unei persoane. Dacă cineva dorește să corecteze un cuvânt sau o literă din Coran, întreaga armonie a Cărții Divine va fi încălcată. Nici un cuvânt din Coran nu ar trebui schimbat, altfel sensul și fonetica se vor schimba. Știm că unele cuvinte tind să devină depășite în timp și nu le folosim. Și limba Coranului nu și-a pierdut relevanța de 1439 de ani... Predau Coranul de peste 10 ani și până în ziua de azi nu m-am întâlnit cu unul dintre elevii mei care să-mi pună o întrebare: „De ce studiem Coranul? De unde a venit? Ce beneficii are? Ce o face diferită de lectura de la stânga la dreapta?” Zi de zi, numărul persoanelor care doresc să studieze alfabetul arab și regulile tajwid-ului crește, pentru ca ulterior să poată citi Coranul din original. Dar puțini oameni se gândesc la răspunsul la întrebările de mai sus. Și, în sfârșit, când le spun despre beneficiile Coranului, despre beneficiile sale, mulți încep să aprofundeze în acest sens. Limba arabă are 29 de litere. Sunetele se formează la marginea laringelui, în mijlocul laringelui, piept, între rădăcina limbii și cavitatea bucală. Sunetele limbii arabe „curăță” cavitatea bucală și sunt mai puțin susceptibile la boli. De asemenea, araba este un bun logoped. Vindecă lisp și pronunțarea greșită a literei „r”. Acest limbaj îi ajută și pe cei cu deficiențe de vedere. Pentru că citirea textului arab de la stânga la dreapta îmbunătățește aparatul vizual al unei persoane și o relaxează. Forma ovală, rotundă a literelor este bună și pentru psihic. Toate literele alfabetului arab sunt consoane. Nu există litere speciale pentru sunetele vocale. Se face o distincție între vocalele scurte și cele lungi. Vocalele scurte sunt transmise în scris folosind vocale - superscripte și subindice. De asemenea, din 28 de litere, 22 de litere sunt conectate pe ambele părți, iar 6 litere sunt conectate doar pe dreapta. Coranul a ajuns până la noi timp de 23 de ani fără distorsiuni. Coranul este ultima carte divină și nu vor mai fi alte cărți după el. El a fost trimis la toată omenirea. Legile Coranului vor rămâne în vigoare până în ziua judecății și nu se vor schimba. Coranul este o minune veșnică, mare a Celui Atotputernic, dăruită Profetului Muhammad (s.a.s.). Citirea Coranului este închinare. Îi sfătuiesc pe toți să citească în fiecare zi această carte incredibil de minunată și să-i cunoască sensul. Grăbește-te să înveți cum să citești și să vorbești cu Creatorul tău. Allah ne va da să fim locuitori ai lui Jannat și să vorbim limba arabă, pe care El Însuși a ales-o. Dilyar Bektayeva, ustaz din Aktobe regional Moscheea centrală „Nur Kasyr” http://nurgasyr.kz/index.php/ma-alar/1826-yazyk-zhitelej-dzhannata
RĂSPUNS:
wa aleikum ca salam frate! Așa cum ea, „fals ustaz” de casă și ignorantă ar trebui alungată de musulmani, pentru a nu-i induce în eroare. Odată ajunsă în moscheea Aktobe se răspândesc astfel de prostii și sunt ținuți profesori ignoranți, poate de aceea sunt atât de mulți sectari extremiști în acest oraș. Nici Coranul, nici Sunnah nu conțin nici măcar un indiciu îndepărtat că limba arabă va fi o limbă comună pentru toți locuitorii Paradisului. Gândiți-vă singur cum vor comunica reprezentanții altor naționalități între ei în Paradis dacă nu cunosc limba arabă?! Am răspuns anterior la o întrebare similară:Date denumite
Lucrul cu memoria prin adrese fizice
Operații suplimentare pentru lucrul cu date și memorie
Comenzi de control al procesorului
Dicţionar Commands
comenzi I/O
Gestionarea întreruperilor și a excepțiilor
„Limba arabă este limba locuitorilor Paradisului!” (Semnificație aproximativă)
Dragi frați, vă rog să clarificați întrebarea referitoare la acest hadith, este de încredere? În general, sunt aceste cuvinte cuvintele profetului Muhammad, alayhi salty wa salam?
barakALLAHU fikum wa jazakumu Allahu hayran!
„Trimisul lui Allah (pacea și binecuvântările lui Allah fie asupra lui) a spus: „Sunt arab, Kuran este în arabă, iar limba vilelor Paradisului va fi arabă”.
Sheikhul-Islam Ibn Taymiyyah (Allah să aibă milă de el) a fost întrebat: „Ce limbă vor vorbi oamenii în Ziua Învierii? Va vorbi Allah Atotputernicul oamenilor în arabă? Și este adevărat că limba locuitorilor Iadului este persană, iar locuitorii Paradisului sunt arabi?
La care el a răspuns: „Lăudat să fie Allah, Domnul lumilor! Nu se știe ce limbă vor vorbi oamenii în ziua aceea, cum și ce limbă le va vorbi Domnul lor, El este mare și glorios. Nici Allah Atotputernicul, nici Trimisul Său, pacea și binecuvântările fie asupra lui, nu ne-au spus nimic despre aceasta și nici nu este de încredere că limba locuitorilor Iadului va fi persană, iar limba locuitorilor paradisului va fi arabă. Și nu știm că cu această ocazie printre Însoțitori, Allah să fie mulțumit de ei, a existat vreo neînțelegere. Dimpotrivă, s-au abținut să o facă, pentru că a vorbi despre asta este inutil. Cu toate acestea, a existat un dezacord între generațiile următoare cu privire la această problemă. Unii au spus că vor comunica în arabă, alții au spus că acest lucru nu se aplică locuitorilor Iadului, deoarece vor răspunde în persană și aceasta este limba lor în Iad. Alții - că oamenii vor comunica în asirian, deoarece aceasta este limba lui Adam, din care au provenit toate celelalte limbi. În al patrulea rând, că acest lucru nu se aplică locuitorilor Paradisului, deoarece vor comunica în arabă. Cu toate acestea, niciunul dintre ei nu are un argument în favoarea cuvintelor lor, nici din rațiune, nici din surse Sharia, dar acestea sunt doar afirmații lipsite de orice dovadă. Allah Atotputernicul știe mai bine!” Vezi Majmu'ul-Fataawa 4/299.Poate fi tradusă Scriptura?
Este cu adevărat în paradis–rece?
Toți slavii au înțeles Biblia?
Limbile sunt apropiate și... paralele
Preot sau Păstor?
Traduceri sacre și profane
Răspunsuri la întrebări