String instrukcije

U asembleru posteje neke vrlo korisne instrukcije koje manipulisu sa stringovima. Ovde je data lista nekih instrukcija i njihova sintaksa.

MOV* Pomera string: pomera bajt, rec ili duplu rec sa DS:SI u ES:DI
Sintaksa:

movsb 	; pomera bajt
movsw 	; pomera rec
movsd 	; pomera duplu rec
CMPS* Uporedjuje stringove: uporedjuje bajt, rec ili duplu rec iz DS:SI sa ES:DI
Sintaksa:
cmpsb     ; uporedjuje bajt
cmpsw     ; uporedjuje rec
cmpsd     ; uporedjuje duplu rec
Bitno: Ova instrukcija se najcesce koristi sa REP prefiksom.

SCAS* Trazi string: trazi bajt iz AL, rec iz AX, ili duplu rec iz EAX u stringu na ES:DI
Sintaksa:

scasb     ; trazi bajt iz AL
scasw     ; trazi rec iz AX
scasd     ; trazi duplu rec iz EAX
Note: Ova instrukcija se najcesce koristi sa REPZ ili REPNZ prefiksom.

REP Prefiks za string instrukcije, ponavlja instrukciju CX puta.
Sintaksa:

rep StringInstrukcija
STOS* Pomera bajt, rec ili duplu rec iz AL, AX ili EAX u ES:DI
Sintaksa:
stosb     ; pomera AL u ES:DI
stosw     ; pomera AX u ES:DI
stosd     ; pomera EAX u ES:DI
LODS* Pomera bajt, rec ili duplu rec iz DS:SI u AL, AX ili EAX
Sintaksa:
lodsb     ; pomera ES:DI u AL
lodsw     ; pomera ES:DI u AX
lodsd     ; pomera ES:DI u EAX
Sledeci primer pokazuje kako treba koristiti ove instrukcije.
Listing 11: 11.asm

; program za demonstraciju rada sa string instrukcijama

.model small
.stack

.data
CR equ 13
LF equ 10
NewLine db CR,LF,"$"

String1  db "Ovo je string!$"
String2  db 15 dup(0)
Drugi1   db "Ovaj string je skoro isti kao Drugi2$"
Drugi2   db "Ovaj string je skoro isti kao Drugi1$"
Poruka   db "Ovo je poruka."
NadjiStr db "1293ijdkfjiu938uHello983fjkfjsi98934$"

Poruka1 db " * Program koji ilustruje koriscenje string instrukcija. *$"
Poruka2 db CR,LF,"String1 je sada: $"
Poruka3 db CR,LF,"String2 je sada: $"
Poruka4 db CR,LF,"Stringovi su jednaki!$"
Poruka5 db CR,LF,"Stringovi nisu jednaki!$"
Poruka6 db CR,LF,"Karakter je nadjen.$"
Poruka7 db CR,LF,"Karakter nije nadjen.$"

.code 
mov ax,@data 		
mov ds,ax 		
mov es,ax               ; dodali smo i es

mov ah,9                ; funkcija 9h - prikazi string
mov dx,OFFSET Poruka1   ; ds:dx ukazuje na poruku
int 21h                 ; poziv DOS servisa

cld                     ; Obrisi flegove
mov si,OFFSET String1   ; neka ds:si ukazuje na String1
mov di,OFFSET String2   ; neka es:di ukazuje na String2
mov cx,18               ; duzina stringa
rep movsb               ; kopiraj String1 u String2

mov ah,9                ; funkcija 9h - prikazi string
mov dx,OFFSET Poruka2   ; ds:dx ukazuje na poruku
int 21h                 ; poziv DOS servisa

mov dx,OFFSET String1   ; prikazi String1
int 21h                 ; poziv DOS servisa

mov dx,OFFSET Poruka3   ; ds:dx ukazuje na poruku
int 21h                 ; poziv DOS servisa

mov dx,OFFSET String2   ; prikazi String2
int 21h                 ; poziv DOS servisa

mov si,OFFSET Drugi1    ; neka ds:si ukazuje na Drugi1 
mov di,OFFSET Drugi2    ; neka es:di ukazuje na Drugi2 
mov cx,39               ; duzina stringa
repz cmpsb              ; uporedi stringove
jnz NisuJednaki           ; skok ako nisu jednaki

mov ah,9                ; funkcija 9h - prikazi string
mov dx,OFFSET Poruka4   ; ds:dx ukazuje na poruku
int 21h                 ; poziv DOS servisa

jmp SledecaOperacija

NisuJednaki:
mov ah,9                ; funkcija 9h - prikazi string
mov dx,OFFSET Poruka5   ; ds:dx ukazuje na poruku
int 21h                 ; poziv DOS servisa

SledecaOperacija:
mov di,OFFSET NadjiStr  ; neka es:di ukazuje na string
mov cx,36               ; duzina stringa
mov al,'H'              ; karakter koji se trazi
repne scasb             ; nadji prvi karakter koji odgovara
jnz NijeNadjeno

mov ah,9                ; funkcija 9h - prikazi string
mov dx,OFFSET Poruka6   ; ds:dx ukazuje na poruku
int 21h                 ; poziv DOS servisa
jmp LodsbPrimer

NijeNadjeno:
mov ah,9                ; funkcija 9h - prikazi string
mov dx,OFFSET Poruka7   ; ds:dx ukazuje na poruku
int 21h                 ; poziv DOS servisa

LodsbPrimer:
mov ah,9                ; funkcija 9h - prikazi string
mov dx,OFFSET NewLine   ; ds:dx ukazuje na poruku
int 21h                 ; poziv DOS servisa

mov cx,14               ; duzina stringa
mov si,OFFSET Poruka    ; DS:SI - address of string
xor bh,bh               ; video strana - 0
mov ah,0Eh              ; funkcija 0Eh - ispisi karakter
SledeciKarak:
lodsb 	                ; AL = sledeci karakter u stringu
int 10h                 ; poziv DOS servisa
loop SledeciKarak

mov ax,4C00h            ; zavrsetak programa
int 21h 

end 

Kako saznati verziju DOS-a

U mnogim programima je neophodno saznati koju verziju DOS-a imate na racunaru. To je zato sto mozda koristite DOS finkciju koje nema u starijim verzijama DOS-a

Kao prvo ovaj metod jednostavno saznaje koja je verzija u pitanju.

mov ah,30h    ; funkcija 30h - saznaj MS-DOS verziju
int 21h       ; poziv DOS servisa
Ova funkcija vraca glavni broj verzije u AL a promenu verzije u AH. Na primer ako je verzija 4.01, u AL ce biti 4 a u AH 01. Problem je sto u DOS verzijama preko 5 SETVER moze promeniti verziju. Nacin da se to zaobidje je:
mov ah,33h ; funkcija 33h - stvarna DOS verzija mov al,06h ; podfunkcija 06h int 21h ; poziv prekida 21h
Ovo ce naravno raditi na DOS verzijama koje su 5 ili vece, pa zato morate prvo proveriti koristeci prosli metod. Ovo ce vratiti pravu verziju DOS-a cak i ako ga je SETVER promenio.Ova funkcija vraca glavni broj verzije u BL a promenu verzije u BH.

Koriscenje SHIFT za brze mnozenje i deljenje

Koriscenje MUL-a i DIV-a je veoma sporo i treba ih koristiti samo kada brzina nije presudna. Za brze mnozenje ili deljenje mozete pomerati brojeva levo ili desno za jednu binarnu poziciju. Svaki pomeraj je mnozenje ili deljenje sa dva. To je isto kao << i >> operatori u C-u.

Postoje cetiri nacina za pomeranje brojeva ili desno ili levo za jednu binarnu poziciju.

SHL neoznaceno mnozenje sa dva (pozitivno)
SHR neoznaceno deljenje sa dva (pozitivno)
SAR oznaceno deljenje sa dva
SAL isto kao SHL

Sintaksa za sve cetiri je ista:

SHL operand1,operand2
Bitno: 8086 ne moze da ima vrednost operand2 drugaciju od 1. 286/386 ne moze da ima operand2 vece od 31.

LOOP instrukcija

Koriscenje Loop instrukcije je bolji nacin za pravljenje petlji u programu od JMP instrukcije. Da bi ste zadali koliko puta da se petlja izvede koristite CX. U njega smestite broj ponavljanje\a petlje i svaki put kada se stigne do instrukcije Loop CX se umanji za jedan i onda skoci na labelu koja je zadata. Pomocu ovakve petlje mozete da skocite samo 128 bajtova pre ili 127 bajtova posle Loop instrukcije.

Sitaksa:

mov cx,100    ; petlja ce se izvrsiti 100 puta
Labela:
.
. 
.
Loop Labela:  ; dekrementira CX i skace na "Labela"
Ovo je isto kao i sledeci kod ali bez koriscenja Loop instrukcije:
mov cx,100    ; petlja se izvrsava 100 puta

Labela:
dec cx        ; CX = CX-1
jnz Labela    ; skok na "Labela"

Ovo ce raditi jer JNZ ce skociti ako nije postavljen ZERO fleg a on ce biti postavljen kada CX stigne do niula i tada se zavrsava petlja.

Sadrzaj