Scrigroup - Documente si articole

     

HomeDocumenteUploadResurseAlte limbi doc
AccessAdobe photoshopAlgoritmiAutocadBaze de dateC
C sharpCalculatoareCorel drawDot netExcelFox pro
FrontpageHardwareHtmlInternetJavaLinux
MatlabMs dosPascalPhpPower pointRetele calculatoare
SqlTutorialsWebdesignWindowsWordXml

Componentele arhitecturii ISA x86

calculatoare



+ Font mai mare | - Font mai mic



Componentele arhitecturii ISA x86

In continuare se prezinta acele componente ale unui procesor care sunt vizibile si accesibile pentru un programator in limbaj de asamblare. Astfel, un procesor dispune de un set de registre interne folosite pentru pastrarea temporara a datelor, a adreselor sau a instructiunilor. Exista registre generale folosite in majoritatea operatiilor aritmetico-logice si registre speciale, care au o destinatie speciala.



La arhitectura ISA x86 pe 16 biti exista 8 registre generale pe 16 biti, registre denumite in felul urmator: AX, BX, CX, DX, SI, DI, BP, SP. Dintre acestea primele patru se folosesc cu precadere in operatii aritmetico-logice pentru pastrarea operanzilor, iar urmatoarele patru mai ales pentru pastrarea si calculul adreselor de operanzi. Primele patru registre se pot adresa si pe jumatate, adica la nivel de octet. Astfel fiecare registru are o parte superioara 'HIGH' (bitii D15-D8) si o parte inferioara 'LOW' (bitii D7-D0). Denumirea lor este AH si AL pentru registrul AX, BH si BL pentru registrul BX si asa mai departe.

La procesoarele pe 32 de biti (incepand de la '386) aceste registre s-au extins la 32 de biti. Astfel registrele pot fi adresate pe 32 de biti (cu denumirile EAX,EBX, ECX, ESP) sau in mod uzual pe 16 sau 8 biti. Partea superioara a unui registru pe 32 de biti (D31-D16) nu se poate adresa individual.

In principiu registrele generale respecta principiul de ortogonalitate, adica pentru majoritatea operatiilor oricare registru este utilizabil. La unele procesoare (ex: procesoarele Motorola) acest principiu este respectat strict. In cazul procesoarelor Intel anumite operatii speciale impun utilizarea anumitor registre, ceea ce inseamna ca exista o oarecare specializare intre registre. Aceasta specializare decurge de multe ori si din denumirea registrelor. Astfel:

registrul AX (EAX in varianta pe 32 de biti) - se foloseste ca registru 'acumulator' in majoritatea operatiilor aritmetice si logice, adica pastreaza unul dintre operanzi si apoi rezultatul operatiei; la operatiile de inmultire si impartire in mod obligatoriu primul operand si rezultatul se pastreaza in acest registru

registrul BX (EBX) - se foloseste pentru in operatii aritmetico-logice sau pentru calculul adresei operandului la 'adresarea bazata'

registrul CX (ECX) - se foloseste pentru operatii aritmetico-logice sau in mod implicit, la anumite instructiuni (ex: instructiuni de buclare), pe post de contor

registrul DX (EDX) - se foloseste pentru operatii aritmetico-logice sau pentru pastrarea adresei porturilor la instructiunile de intrare/iesire; de asemenea la operatiile de inmultire si impartire se foloseste ca extensie a registrului acumulator

registrele SI si DI (ESI, EDI) - denumite si registre index, se folosesc cu precadere pentru calculul adresei operanzilor la 'adresarea indexata'; SI adreseaza elementele sirului sursa (source index), iar DI elementele sirului destinatie (destination index)

registrul BP (EBP) - se foloseste cu precadere pentru calculul adresei operanzilor la 'adresarea bazata', alaturi de registrul BX

registrul SP (ESP) - se foloseste aproape in exclusivitate pentru adresarea stivei (stack pointer); continutul registrului se incrementeaza si se decrementeaza automat la orice operatie cu stiva

In afara registrelor generale un procesor mai are si registre speciale sau de control. La procesoarele Intel numai o parte din aceste registre sunt vizibile si accesibile pentru programator. Aceste registre controleaza regimul de lucru al procesorului, sau permit efectuarea unor operatii speciale de manipulare a spatiului de memorie.

Arhitectura ISA x86 opereaza cu urmatoarele registre speciale:

registrul PC - 'program counter' - pastreaza adresa instructiunii care urmeaza; nu este adresabil direct (prin nume) dar continutul sau se poate modifica prin executia instructiunilor de salt

registrul PSW - 'program status word' - pastreaza indicatorii de stare ai procesorului;

o       o parte din indicatori caracterizeaza rezultatul obtinut in urma unei anumite instructiuni:

ZF - rezultat 0,

SF - semnul rezultatului

OF - 'overflow' indica o depasire de capacitate la ultima operatie aritmetica

PF - indicator de paritate (arata paritatea rezultatului)

CF - indicator de transport ('carry'), arata daca s-a generat un transport

AC - indicator de transport auxiliar, arata daca dupa primii 4 biti s-a generat un transport

o       o parte din indicatori controleaza modul de lucru al procesorului:

IF - indicator de intrerupere (interrupt'), daca este setat (1 logic) atunci se blocheaza toate intreruperile mascabile, in caz contrar (0 logic) se valideaza

DF - indicatorul de directie, arata directia de parcurgere a sirurilor de caractere la instructiunile pe siruri (in ordine ascendenta sau descendenta a adreselor)

registrele de segment - se utilizeaza pentru calculul adresei operanzilor si a instructiunilor; cu ajutorul lor memoria este divizata in segmente; exista 4 registre segment in versiunea initiala ISA x86 si 6 registre segment in versiunea pe 32 de biti:

o       registrul CS - registrul segment de cod, folosit pentru adresarea instructiunilor (a codurilor); acest registru pastreaza adresa de inceput (descriptorul in varianta extinsa) pentru segmentul de cod (segmentul unde se afla programul)

o       registrul DS - registrul segment de date, folosit pentru adresarea operanzilor din memorie; acest registru pastreaza adresa de inceput (sau descriptorul) pentru segmentul de date

o       registrul SS - registrul segment de stiva, folosit pentru adresarea memoriei stiva; pastreaza adresa de inceput (descriptorul) segmentului unde se afla organizata stiva

o       registrul ES - registrul extra-segmentului de date, folosit pentru pastrarea adresei celui de al doilea segment de date

o       registrele FS si GS - registre segment introduse incepand de la versiunea '386 si care se folosesc pentru adresarea operanzilor

Versiunile mai noi de procesoare contin si alte registre speciale, dar acestea au o importanta mai mica pentru un programator obisnuit. Ele vor fi introduse pe parcurs in momentul in care acest lucru va fi necesar.

Organizarea memoriei

Arhitectura ISA x86 promoveaza o modalitate originala de organizare a memoriei. Spatiul de memorie este divizat in regiuni de numite segmente, iar adresa unei locatii de memorie se exprima printr-o pereche de adrese: <adresa de segment>:<adresa de offset>. Adresa de segment indica punctul de inceput al unei zone de memorie, iar adresa de offset adresa relativa a locatiei cautate in raport cu inceputul de segment. La aceasta solutie s-a ajuns atat datorita unor cauze obiective cat si datorita unor limitari tehnologice care ulterior au fost depasite (ex: generarea unei adrese pe 20 de biti folosind doar registre pe 16 biti).

Adresarea pe segmente a memoriei are urmatoarele avantaje:

adresa relativa in cadrul segmentului (adresa de offset) se exprima pe un numar mai mic de biti; astfel instructiunile care contin adrese sunt mai scurte

incarcarea si reamplasarea programelor si a datelor este mai simpla deoarece adresele relative raman aceleasi

exista posibilitatea protejarii diferitelor zone de memorie pe baza de continut si functie de drepturile de acces

se pot incarca in memorie numai acele segmente ale unei aplicatii care sunt strict necesare

un sistem de operare de tip multi-tasking sau multi-utilizator are nevoie in mod obligatoriu de un sistem de partajare si de protectie a zonelor de memorie

La ISA x86 tehnica de segmentare folosita depinde de modul de lucru al procesorului: modul real sau modul protejat. La primele variante de procesoare exista numai modul real; ulterior, pentru a oferi suport pentru multitasking si pentru a creste spatiul de adresare s-a introdus modul protejat. In majoritatea cazurilor programele scrise de programatorii obisnuiti folosesc modelul initial de segmentare, desi procesorul lucreaza in modul protejat. Acest lucru este posibil prin faptul ca programul poate sa ruleze intr-un al treilea mod, modul virtual, care este o simulare a modului real pe un procesor aflat in modul protejat. In mod uzual operatiile care afecteaza functionarea in modul protejat sunt efectuate numai de rutine ale sistemului de operare. Mai mult alocarea memoriei este responsabilitatea sistemului de operare. utilizatorul obisnuit are senzatia lucrului in modul real, mod care este mult mai simplu.

Organizarea memoriei in modul real

In modul real spatiul maxim de adresare al memoriei este de 1Moctet. Aceasta memorie este impartita in segmente de lungime fixa de 64Kocteti. Adresa de inceput a unui segment se pastreaza in unul din cele patru registre segment. Deoarece un registru segment are doar 16 biti, in el se pastreaza doar partea mai semnificativa a adresei de segment, ultimii 4 biti considerandu-se in mod implicit 0. Adresa fizica a unei locatii de memorie se calculeaza ca o suma intre adresa de segment si o adresa de offset. Adresa de segment se obtine prin multiplicarea continutului registrului segment cu 16 (deplasarea la stanga cu 4 pozitii binare). Adresa de ofset se calculeaza pe baza modului de adresare si eventual a adresei continute in codul de instructiune. Prin adunare se obtine o adresa fizica pe 20 de biti, suficienta pentru adresarea unui spatiu de 1 Mocteti (1M=220). In exemplul de mai jos, pentru claritate, valorile de adrese sunt exprimate in hexazecimal.

Adresa de segment

 


Acest mod de calcul a adresei fizice are cateva consecinte:

spatiul maxim de adresare este 1Mo

un segment trebuie sa inceapa la o adresa multiplu de 16

un segment are maxim 64ko

segmentele se pot suprapune partial sau total

aceeasi locatie fizica se poate exprima prin mai multe variante de perechi de adrese (segment:offset)

exista putine posibilitati de protejare a zonelor de memorie

orice program poate adresa orice locatie de memorie, neputandu-se impune restrictii (lucru nedorit intr-un sistem multitasking)

Cele patru registre segment se utilizeaza in mod implicit functie de tipul de informatie care se adreseaza:

CS - pentru adresarea instructiunilor

DS - pentru adresarea datelor

SS - pentru adresarea stivei

ES - in anumite cazuri speciale pentru adresarea sirurilor

Programatorul poate solicita in mod explicit utilizarea unui anumit registru segment prin amplasarea unui prefix cu numele registrului (ex: ES:) in fata operandului adresat. In mod uzual insa compilatorul este cel care detecteaza daca utilizarea explicita a unui registru segment este necesara (de exemplu o variabila nu se afla in segmentul indicat de registrul DS).

Organizarea memoriei in modul protejat

Modul protejat s-a introdus odata cu procesorul '386 si apoi s-a perfectionat la procesorul '486. Acest mod a fost necesar pentru a solutiona limitarile modului real, in special in ceea ce priveste spatiul limitat de adresare si posibilitatile reduse de protectie.

In modul protejat exprimarea adresei se face la fel prin adresa de segment si adresa de offset, insa cu anumite amendamente:

un registru segment pastreaza un selector de segment si nu adresa de inceput a segmentului;

selectorul este un indicator care arata locul unde se afla o structura de date care descrie un segment si care poarta numele de descriptor de segment

un descriptor de segment contine: adresa segmentului (pe 32 de biti) lungimea segmentului (pe 20 de biti), indicatori pentru determinarea drepturilor de acces si indicatori care arata tipul si modul de utilizare a segmentului

adresa de offset se exprima pe 32 de biti

Aceste modificari genereaza urmatoarele consecinte:

spatiul maxim de adresare al memoriei se extinde la 4Gocteti (4G = 232)

un segment are o lungime variabila, in interval larg de la 1 octet la 4Gocteti

se definesc trei nivele de protectie (0, cel mai prioritar)

un segment este accesibil numai taskului alocat si eventual sistemului de operare

anumite segmente pot fi blocate la scriere (ex: segmentele de cod)

rezulta un mecanism complex de alocare si de protectie a zonelor de memorie


Elementele limbajului de asamblare si formatul programelor executabile

Scopul lucrarii este prezentarea formatului instructiunilor in limbaj de asamblare, a principalelor pseudoinstructiuni pentru lucrul cu segmente si rezervare a datelor precum si a structurii programelor executabile de tip .COM si .EXE

Formatul instructiunilor

O instructiune se poate reprezenta pe o linie de maxim 128 caractere, avand forma generala:

[<eticheta>:] [<codop>[<operanzi>][;<comentarii>]]

unde:

<eticheta> un nume, maxim 31 caractere (litere, cifre sau caractere speciale _,?,@,..), primul caracter fiind litera sau unul din caracterele speciale. Fiecare eticheta are asociata o valoare si anume adresa relativa in segmentul din care face parte

<codop> mnemonica instructiunii

<operanzi> operandul (sau operanzii) asociat instructiunii conform sintaxei cerute de aceasta. Poate fi o constanta, un simbol sau expresii continand acestea

<comentarii> un text oarecare precedat de caracterul ";"

Este permisa inserarea de linii goale si a unui numar oarecare de spatii. Aceste facilitati se folosesc pentru asigurarea lizibilitatii programului

Specificarea constantelor

Constante numerice - se prezinta sub forma unui sir de cifre, prima fiind intre 0 si 9 (daca de exemplu numarul este in hexa si incepe cu un caracter, se va pune un zero in fata acestuia). Baza numarului se specifica printr-o litera la sfarsitul numarului (B pentru binar, Q pentru octal, D pentru zecimal si H pentru hexa; fara o specificatie explicita, numarul se considera in zecimal).

Exemple: 010010100B, 26157Q (octal), 7362D (sau 7362), 0AB3H.

Constantele caracter sau siruri de caractere se specifica intre ghilimele sau apostrof.

Exemple: "sir de caractere", 'sir de caractere'

Etichete

Etichetele (label) se pot defini numai pe zona de program si pot fi operanzi la instructiunile CALL sau JMP

Atributele etichetelor sunt:

segmentul (de regula CS) este adresa paragrafului unde incepe segmentul care contine eticheta. Cand se face referire la eticheta, valoarea se gaseste in CS (valoarea efectiva se stie numai in timpul rularii)

offset-ul este distanta in octeti a etichetei fata de inceputul segmentului in care acesta a fost definit

tipul determina modul de referire la eticheta; exista doua tipuri: NEAR si FAR. Referirea de tip NEAR este in segment (numai offset) iar cea de tip FAR precizeaza si segmentul (segment : offset).

Etichetele se definesc la inceputul liniei sursa. Daca dupa eticheta urmeaza caracterul ":" atunci va fi de tip near.

Variabile

Definirea variabilelor (eticheta de date) se poate face cu pseudooperatori de rezervare a spatiului.

Atributele variabilelor sunt:

- Segment si offset - ca si la etichete, cu deosebirea ca pot fi si alte registre segment

- tipul - este o constanta care arata lungimea (in octeti) a zonei rezervate:

BYTE(1), WORD(2), DWORD(4), QWORD(8), TWORD(10), STRUC (definita de utilizator), RECORD (2).

Exemple:

mov al,dat ; al<-0fh

mov ax,datw ; al<-0fh, ah<-07h

mov ax,dat ; eroare de tip

Expresii

Expresiile se definesc prin constante, simboluri, pseudooperatori si operatori (pentru variabile se considera numai adresa si nu continutul, deoarece la compilare se cunoaste doar adresa)

Pseudoinstructiuni de lucru cu segmente

Orice segment este identificat de un nume si o clasa, ambele specificate de utilizator. La definire segmentele primesc o serie de atribute care specifica pentru asamblor si editorul de legaturi relatiile dintre segmente.

Definirea segmentelor se face cu secventa:

nume_seg SEGMENT [align_type] [combine type] ['class']

nume_seg ENDS

unde:

nume_seg - este numele segmentului ales de utilizator. (numelui i se asociaza o valoare - la executie - corespunzator pozitiei segmentului in memorie)

align_type - este tipul de aliniere a segmentului (in memorie). Poate sa ia valorile

PARA (aliniere la paragraf, multiplu de 16 octeti)

BYTE (aliniere la octet)

WORD (aliniere la cuvant)

PAGE (aliniere la pagina - multiplu de 256 octeti)

combine_type - este de fapt tipul segmentului si reprezinta o informatie pentru link-editor specificand in ce raport sunt segmentele cu acelasi nume. Poate fi:

PUBLIC - specifica concatenarea

COMMON - specifica suprapunerea

AT expr - specifica incarcarea segmentului la adresa expr*16

STACK - arata ca segmentul curent va face parte din segmentul stiva

MEMORY - specifica asezarea acestui segment ca ultimul segment din program

'class' - este clasa segmentului; editorul de legaturi dispune continuu segmentele cu aceeasi clasa in ordine aparitiei. Se recomanda utilizarea claselor 'code', 'data', 'constant', 'memory', 'stack'.

Desemnarea segmentului activ

Intr-un program pot fi definite mai multe segmente (de date si de cod). Asamblorul verifica daca datele sau instructiunile adresate pot fi atinse cu registrul segment avand un anumit continut. Pentru a se realiza acest lucru in conditii bune trebuie sa se comunice asamblorului segmentul activ, adica in registrul segment sa fie adresa segmentului incarcat

ASSUME <reg-seg>:<nume-seg>, <reg_seg>:<nume-seg>

reg-seg - registrul segment

nume-seg - segmentul care va fi activ cu registrul segment respectiv

Exemplu:

ASSUME CS:prg, DS:date1, ES:date2

Observatii:

- pseudoinstructiunea NU pregateste registrul segment ci doar comunica asamblorului in ce segment trebuie cautate simbolurile

- se recomanda ca DS sa fie initializat la inceputul programului si acest lucru sa fie anuntat asamblorului cu secventa tipica:

ASSUME DS:nume_seg_date

MOV AX, nume_seg_date

MOV DS, AX

- CS nu trebuie initializat dar trebuie activat cu ASSUME inainte de prima eticheta

- in loc de nume-seg din ASSUME se poate folosi identificatorul NOTHING daca nu dorim sa asociem registrului nici un segment

Rezervarea zonei de date

De regula datele sunt definite intr-un segment de date. Pseudoinstructiunea de definitie are forma:

<nume> <tip> [lista expresii] [<factor> DUP (<lista expresii>)]

unde:

nume - este numele simbolului (a etichetei de date)

tip este tipul simbolului:

DB - pentru rezervare de octet

DW - pentru rezervare de cuvant (2 octeti)

DD - pentru rezervare de cuvant dublu (4 octeti)

DQ - pentru rezervare de cuvant cvadruplu (8 octeti)

DT - pentru rezervare de 10 octeti

lista expresii - o expresie cu rezultatul careia se initializeaza zona rezervata; se scrie caracterul "?" daca zona nu se va initializa

factor - o constanta care arata de cate ori se repeta expresia de dupa DUP

Exemple:

DAT db 45

dat1 db 45h, 'a', 'A", 85h

dat2 db 'abcdefghi' ; se genereaza textul

lg_dat2 db $-dat2 ; lungimea sirului dat2 ($ este contorul locatiei curente)

aa db 100 dup(56h) ; 100 de octeti cu valoarea 56h

bb db 20 dup (?) ; 20 de octeti neinitializati

ad dw dat1 ; contine adresa (offset-ul) variabilei dat1

adr dd dat1 ; contine adresa (offset + segment) variabilei dat1

var1 db 12h,5, 33, 10101111b

x dw 1234h, 0ff00h

litera byte 'A'

text byte 'TEXT'

dublu dd 12345678h

Corespunzator acestor declaratii, in memorie se vor regasi urmatoarele date:


Lucrarea de laborator

1.Programul trebuie sa calculeze suma unui sir de numere aflat la adresa SIR si lungime specificata in variabila LGSIR; rezultatul va fi in locatia SUMA. (Ex31.asm). Rectificati greseala in codul sursa de mai jos.

.model small

.data

sir db 1,2,3,4

lgsir db $-sir

suma db 0

.stack 512

.code

mov ax,@data

mov ds,ax

start: jmp eticheta1

eticheta1:

mov ch,0

mov cl,lgsir ; in cx (contor) lungimea sirului

mov al,0 ; initializarea registrului in care se calculeaza suma

mov si,0 ; initializarea indexului

next:

add al,sir[si] ; adunarea elementului curent

inc si ; trecerea la elementul urmator in sir

loop next ; decrementare cx si salt la urmatorul

; element daca cx diferit de 0

mov suma,al

mov ah,4ch ; terminare program

int 21h

end start

2.Precizati care este functionalitatea programului de mai jos Ex32.asm).

stiva segment stack

db 512 dup(?)

stiva ends

date segment

rez db 8 dup(?)

mes db 'introdu un numar mai mic decat 9 ptr calcul factorial:$'

a3 db 10,13,?,'!(factorial)=$'

date ends

cod segment

assume cs:cod,ds:date,ss:stiva

start:

mov ax,date

mov ds,ax

xor ax,dx

;afisare mesaj

mov ah,09h

lea dx,mes

int 21h

;citire de la tastatura a unui caracter

mov ah,01h ; codul ascii al caracterului introdus

int 21h ;se va regasi in al

mov a3+2,al

sub al,30h ; se obtine cifra tastata in hexazecimal

mov cl,al

mov ax,01

;calculare factorial in ax

et2:

mul cx ; se inmulteste ax cu cx si rezultatul va fi in dx si ax

loop et2 ; daca cx e diferit de 0 se repeta

xor si,si ; si devine 0

mov bx,0ah

et3:

div bx ;catul va fi in ax restul in dx

add dl,30h ;calcul in ascii a cifrei rezultate si transferarea in memorie

mov rez[si],dl ; utilizand adresarea indexata

inc si

xor dx,dx ; pregatire dx ptr urmatoarea impartire

cmp ax,0 ; conditia de sfarsit de algoritm

jne et3

;afisare rezultat

mov ah,09h ;apelarea functiei 09h ptr afisarea unui mesaj a carui adresa ;relativa e in dx

lea dx,a3

int 21h

et4:

dec si

mov ah,02h ; apelarea functiei 02h ptr afiaarea unui caracter a carui adresa relativa e in dl

mov dl,rez[si]

int 21h ;apelarea functiei 21h ptr afisarea prompt dos

cmp si,0

jne et4

mov ah,4ch

int 21h

cod ends

end start

Exercitii

  1. Se parcurg fazele de asamblare (compilare), editare de legaturi si depanare. In acest scop se lanseaza succesiv un asamblor (TASM), un editor de legaturi (TLINK) si apoi un depanator (TD), dupa cum urmeaza:
  2. Se corecteaza eventualele erori, in programul sursa, dupa care se reiau pasii anteriori.
  3. In programul generat se identifica elementele definite in programul sursa: segmente, variabile, etichete, instructiuni. Se verifica modul de initializare a variabilelor in memorie.
  4. Se implementeaza si se testeaza programele prezentate mai sus.
  5. Sa se scrie o secventa de program care calculeaza media aritmetica a 6 valori aflate in memorie.

Precizati functionalitatea urmatorului program(Ex33.asm).

.model small

.data

nr dw 110

suma dw 0

.stack 1024

.code

start:

mov ax,@data

mov ds,ax

mov ax,nr

xor cx,cx

xor dx,dx

mov bx,10

salt1:

div bx

add cx,dx

xor dx,dx

cmp ax,0

jne salt1

mov suma,cx

mov ax,4c00h

int 21h

end start

Precizati functionalitatea urmatorului program(Ex34.asm).

dosseg

.model small

.stack 100h

.data

a dw 30

b dw 36

c dw 42

mesaj1 db 10,13,'Numerele sunt $'

mesaj2 db 10,13,'Numerele nu sunt .$'

.code

mov ax,@data

mov ds,ax

xor dx,dx

mov ax,a

add ax,c

mov bx,ax

mov cx,2

div cx

cmp ax,b

jne et1

jmp et2

et1:

mov dx,offset mesaj2

mov ah,09h

int 21h

jmp sfarsit

et2:

mov dx,offset mesaj1

mov ah,09h

int 21h

sfarsit:

mov ah,4ch

int 21h

end

Precizati functionalitatea urmatorului program(Ex35.asm).

.model small

.stack 50h

.data

a dw 1h

b dw 5h

.code

mov ax, @data

mov ds, ax

mov ax, a

mov bx, b

mov dl, bl

mov ah, 02h

int 21h

push ax

push bx

mov ax, bx

mov bx, 0

mov dl, bl

mov ah, 02h

int 21h

pop bx

pop ax

mov dl, bl

mov ah, 02h

int 21h

mov ax, 4C00h

int 21h

end start



Politica de confidentialitate | Termeni si conditii de utilizare



DISTRIBUIE DOCUMENTUL

Comentarii


Vizualizari: 2324
Importanta: rank

Comenteaza documentul:

Te rugam sa te autentifici sau sa iti faci cont pentru a putea comenta

Creaza cont nou

Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved