1. Ile razy wykona się poniższa pętla.
mov cx, 15
mov ax, 2
bb: sub cx, ax
xor ax, ax
loop bb
Odp. 13 razy
mov ax, 3
mov cx, 5
xor ax, cx
petla:
loopnz petla
Odp. 5 razy, loopnz i tak zmniejsza cx, a xor na niego nie wpływa.
2. Jaki będzie wynik operacji.
mov bx, bp
mov al, [bx]
mov bl, [bp]
and al, bl
W programie typu EXE, domyślnie bx jest związany z segmentem danych, a bp z segmentem
stosu, a więc do al trafi bajt z adresu DS:BX, a do bl bajt z adresu SS:BP, więc prawie na
pewno będą to różne bajty. al i bl będą więc miały różną zawartość, a ZF (zero flag) w
rejestrze flagowym nie będzie ustawiony.
W programie COM cały program zawiera się w jednym segmencie, więc zawartość al oraz bl
będzie identyczna.
3. Napisać fragment programu drukujący (bez użycia funkcji BIOS/DOS) na środku ekranu
tekstowego literkę A.
mov al,03h ; tryb tekstowy 80x25
mov ah,00h ; ustaw tryb ekranu z al
int 10h ; wykonaj funkcje z ah
; ustawiamy segment grafiki jako segment danych
mov bx,0B800h ; adresowanie posrednie dla
mov ds,bx ; segmentu danych
mov bx,2*40+12*2*80 ; jedna literka to 2 bajty - znak i atrybuty
mov al,'A'
mov [bx],al ; wysylamy gotowy bajt na ekran
4. Zrealizować w asemblerze konstrukcję:
switch(ax) {
case 1:abc(); break;
case 2: def(); break;
case 3: xyz(); break;
};
np.:
cmp ax,1
jne koniec
call abc
jmp koniec
cmp ax,2
jne koniec
1
11. Jak w asemblerze można zrealizować następujący fragment kodu języka C:
static int x;
if (x > 2) {wydrukuj znak 'A';}else{wydrukuj znak 'B'};
x dw (?) ; 16 bitowa zmienna (double word)
cmp x,2
jg wieksze
mov al,'B'
call putchar
jmp koniec
wieksze:
mov al,'A'
call putchar
koniec:
putchar PROC
push ax
mov ah,0Eh ; funkcja: wyswietlanie na ekranie znaku z al
int 10h
pop ax
putchar ENDP
12. W rejestrze al znajduje się bajt. Napisać fragment programu (lub jego schemat blokowy),
który zamienia ten bajt na postać czwórkową do wydruku na konsoli.
mov bh,al ; zapamietamy al w bh
mov bl,11000000b ; jedynki oznaczaja pozycje cyfry do wyswietlenia
mov cl,6 ; w cl bedzie wielkosc przesuniecia bitowego
drukuj_cyfre:
mov al,bh ; odtwarzamy oryginalna wartosc al
and al,bl ; zerujemy wszystkie bity oprocz dwoch z cyfra
shr al,cl ; ustawiamy cyfre na najmlodsze bity al
add al,'0' ; konwertujemy cyfre na ASCII
mov ah,0Eh
int 10h ; wyswietlamy cyfre
shr bl,2 ; bierzemy nastepna cyfre
cmp cl,0
je koniec ; jesli przeszlismy caly bajt al, konczymy
sub cl,2 ; mniejsze przesuniecie dla kolejnej cyfry
jmp drukuj_cyfre
koniec:
13. Przedstawić kompletną procedurę umożliwiającą obliczenie długości napisu, którego adres
znajduje się w rejestrze BX.
strlen PROC ; zapisuje w cx dlugosc napisu na ktory wskazuje bx
push ax ; odkladamy ax na stos, zeby go nie zepsuc dzialaniem procedury
push bx
xor cx,cx ; dlugosc napisu bedzie w cx, na poczatku zero
znak:
mov al,[bx]
cmp al,'$' ; $ oznacza...
je end_znak ; ...koniec napisu
inc cx
inc bx ; przechodzimy do nastepnej litery w napisie
jmp znak
end_znak:
3
call def
jmp koniec
cmp ax,3
jne koniec
call xyz
koniec:
5. Pokazać w jaki sposób bez użycia koprocesora można zrealizować działanie: AX=9*AX.
push ax
shl ax,3
pop bx
add ax,bx
6. Co oznacza zapis xx DW 128 dup(255).
W danym miejscu kodu zostaje umieszczonych 128 slow 00FF. Jeśli mamy do czynienia z
zapisem little endian, to w rzeczywistości w pamięci zostanie umieszczonych 256 bajtów w
formie FF00FF00FF00FF00...
7. Co znajdzie się w rejestrze ax po wykonaniu instrukcji.
mov al,1 ; odp. AX: 0000 0000 0000 0001
mov ah,21 ; odp. AX: 0001 0101 0000 0001
shl ax,1 ; odp. AX: 0010 1010 0000 0010
W ax znajdzie się liczba 10754
8. Napisać fragment kodu drukujący bezpośrednio na środku ekranu w trybie graficznym VGA
pojedynczy pikselek.
mov al,13h ; tryb graficzny VGA 320x200
mov ah,00h ; ustaw tryb ekranu z al
int 10h ; wykonaj funkcje z ah
; ustawiamy segment grafiki jako segment danych
mov bx,0A000h ; adresowanie posrednie dla
mov ds,bx ; segmentu danych
mov bx,160+100*320 ; 320x200 bajtow
mov al,7 ; kolor bialy
mov [bx],al ; wyslij gotowy piksel na ekran
9. Napisz w jaki sposób można rozwiązać w assemblerze konstrukcje if - else.
Załóżmy że if (ax=0) then "xxx" else "yyy"
cmp ax,0
je xxx
yyy:
instrukcje dla „yyy”
jmp next
xxx:
instrukcje dla „xxx”
next:
instrukcje dla „next”
10. W komórce pamięci o adresie fizycznym 0x25394 znajduje się bajt. Napisać fragment
programu umożliwiający wczytanie go do rejestru al.
mov ds,2000h ; tutaj jest SEGMENT
mov bx,5394h ; tutaj jest OFFSET
mov al,[bx] ; adres logiczny to SEGMENT:OFFSET, adres fizyczny to 16*SEGMENT+OFFSET
2
pop bx
pop ax
ret
strlen ENDP
14. Napisać fragment programu, który oblicza wartość delty równania kwadratowego o
współczynnikach rzeczywistych a, b i c.
; wczesniej definiujemy zmienna 32-bitowa (double word)
cztery dd 4
; wykonamy na koprocesorze (FPU) obliczenie: delta=b^2-4ac
finit ; zerujemy koprocesor
fld b ; ladujemy b na stos koprocesora
fld b ; teraz na stosie FPU jest: b, b
; instrukcja fmul mnozy pierwsza i druga liczbe na stosie koprocesora
fmul ; FPU: b^2
fld c ; FPU: c, b^2
fld a ; FPU: a, c, b^2
fld cztery ; FPU: 4, a, c, b^2
fmul ; FPU: 4a, c, b^2
fmul ; FPU: 4ac, b^2
; instrukcja fsubp odejmuje pierwsza liczbe na stosie FPU od drugiej
fsubp ; FPU: b^2-4ac
fstp delta ; zczytujemy liczbe z wierzchu koprocesora do zmiennej delta
fwait ; synchronizacja koprocesora z procesorem
15. Napisać fragment programu, który drukuje na konsoli wszystkie małe litery ASCII.
mov al,'a'
drukuj_litere: ; petla drukujaca na ekranie kolejne litery
mov ah,0Eh ; funkcja drukowania litery z al
int 10h ; drukujemy litere na ekranie
inc al ; bierzemy nastepna litere
cmp al,'z'
jg koniec ; jesli poszlismy dalej niz do 'z', to koniec
jmp drukuj_litere
koniec:
16. Napisać kompletną procedurę, która zamienia kod ASCII (znajdujący się w rejestrze al)
małej litery na dużą (tj odpowiednik al=toupper(al)).
toupper PROC ; zamienia mala litere ASCII z al na wielka litere
cmp al,'a' ; sprawdzamy, czy to mala litera
jl koniec
cmp al,'z'
jg koniec ; jesli nie jest mala litera, nic nie rob
sub al,'a'-'A' ; odejmij od al odleglosc miedzy malymi i wielkimi literami
koniec: ; uwaga: w alfabecie ASCII wielkie litery sa przed malymi
ret
toupper ENDP
4
17. Napisać kompletne makro, które neguje 16 bitową liczbę całkowitą zawartą w rejestrze ax.
W jaki sposób zastosować to makro w programie.
negate MACRO
neg ax
ENDM
; umieszczamy to makro np. na poczatku segmentu kodu, a w kodzie piszemy po prostu:
negate
18. Jak w asemblerze można zrealizować następujący fragment kodu języka C:
static int x=1;
while (x<10) printf("%d\n",x++);
x dw 1 ; zmienna 16-bitowa x o wartosci 1
dopoki:
cmp x,10 ; na poczatku sprawdzamy warunek petli
jge koniec_dopoki ; jesli warunek niespelniony, koniec petli
mov ax,x ; zczytujemy liczbe ze zmiennej
mov ah,0Eh
add al,'0' ; konwersja na ASCII
int 10h ; wypisujemy liczbe (jednocyfrowa)
mov al,0Ah ; line feed
int 10h
mov al,0Dh ; new line (enter)
int 10h
inc x ; x++
jmp dopoki
koniec_dopoki:
19. Napisać program typu COM, który odczytuje z klawiatury znaki oraz liczy ich ilość.
Wciśnięcie klawisza 'x' kończy program. Ilość wprowadzonych znaków ma znajdować się w
rejestrze ax.
rozkazy SEGMENT
ASSUME cs:rozkazy,ds:rozkazy
ORG 100h
main:
xor cx,cx
czytaj_znak:
mov ah,01h ; odczyt znaku z klawiatury, do al kod ASCII znaku
int 21h
cmp al,'x' ; wcisniecie x konczy odczyt z klawiatury
je wczytano1
inc cx
jmp czytaj_znak
wczytano1:
mov ax,cx ; ilosc odczytanych znakow ma byc w ax
mov ah,4Ch ; wyjscie
int 21h ; do DOS
rozkazy ENDS
END main
5
;mozna wydrukowac sobie znak
add al,'0'
mov ah,0Eh
int 10h
jmp next
koniec:
ENDM
23. Jak wygląda stos procesora po niezależnym wykonaniu operacji a) int 21h, b) call
1234:5678, c) pop ax, d) DW 23, e) jmp 1234.
Instrukcja CALL odkłada na stos adres IP, a instrukcja INT odkłada na stos adres CS:IP i FLAGS,
ale po wykonaniu działania wartości te zdejmowane są ze stosu. Zatem przed i po wykonaniu
tych instrukcji stos jest w takim samym stanie.
Instrukcje DW i JMP nie zmieniają stosu.
Instrukcja POP zmieni stos, ściągając z niego wartość do podanego rejestru. SP zmniejszy się o
1.
24. Atoi.
atoi
SEGMENT
ASSUME CS:atoi, DS:atoi, SS:atoi
ORG 0100h
main:
xor cx, cx
mov bx, offset liczba
sznur: mov al, [bx]
and al, al
jz jpk
sub al, 030h
call mnoz
add cx, ax
inc bx
jmp sznur
jpk:
mov ax, cx
call hex
mov ah, 04Ch
int 021h
include
libp.asm
mnoz
PROC
push dx
mov dx, cx
shl cx, 3
shl dx, 1
add cx, dx
pop dx
ret
mnoz
ENDP
liczba
DB
"234",0
atoi
ENDS
END main
7
20. Napisać program, w którym (1) zdefiniowano napis „zdane” zakończony znakiem powrotu
karetki. (2) napis ten należy wydrukować za pomocą procedury „drukowanie” znak po znaku
dużymi literami.
program SEGMENT
ASSUME cs:program, ds:program, ss:program
ORG 0100h
main:
call drukowanie
mov ah,04Ch
int 21h
drukowanie PROC
mov bx, offset napis
xor si,si
next: mov al,[bx+si]
sub al,'a' - 'A' ; zamiana na duza litere
mov ah,0Eh
int 10h
inc si
mov al,[bx+si]
cmp al,0Dh ; 0Dh - karetka
jnz next
ret
ENDP
napis DB "zdane",0Dh
program ENDS
END main
21. Zrealizować w asemblerze fragment realizujący następujący kod w C:
for(i=1;i<10;i++)printf(„%d”,i);
mov cx,1
next: mov al,cl
add al,'0' ; bo drukujemy tylko cyfry
mov ah,0Eh
int 10h
inc cx
cmp cx,10
jl next ; jump if cx less than 10
mov ah,04Ch
int 21h
petla:
mov al,cl
add al,'0'
mov ah,0Eh
int 10h
22. Napisać makro umożliwiające wprowadzanie z klawiatury jedynie cyfr z zakresu 0...9.
eee MACRO
next: mov ah,0h
int 16h
sub al,'0'
cmp al,0
jl koniec ; jump if al less than 0
cmp al,9
jg koniec ; jump if al great than 9
6
25. Binhex.
binhex
SEGMENT
ASSUME CS:binhex, DS:binhex, SS:binhex
ORG 100h
poczatek:
mov al, 91
;zamieniana liczba
;4 MLODSZE BITY
push ax
;kopia liczby
shr al, 4 ;wyluskaj 4 starsze bity
cmp al, 9
;czy al<=9
jle mniej1
;if tak -> skocz
add al, 037h ;if nie -> zamien na litere
jmp wyp1
mniej1:
add al, 030h ;zamien na cyfre
wyp1:
cmp al, 030h ;czy 0
je pomin
;jesli tak, to nie wypisuj
mov ah, 0Eh ;wypisz
int 10h
pomin: ;4 STARSZE BITY
pop ax ;kopia liczby
and al, 15
;wyzeruj 4 starsze bity
cmp al, 9
;czy al<=9
jle mniej2
;if tak -> skocz
add al, 037h ;if nie -> zamien na litere
jmp wyp2
mniej2:
add al, 030h ;zamien na cyfre
wyp2:
mov ah, 0Eh ;wypisz
int 10h
mov ah, 4Ch ;obie linijki powracaja do systemu
int 21h
binhex
ENDS ;zakoncz segment
END poczatek ;zakoncz wykonanie programu
26. Binoct.
binoct
SEGMENT
ASSUME CS:binoct, DS:binoct, SS:binoct
ORG 100h
poczatek:
mov al, 91
;zamieniana liczba
push ax
;zachowanie liczby
mov cx, 3
;licznik petli
petla:
mov bx, cx
;b = c
sub bx, 1
;b = c-1
mul bx, 3
;b = 3*(c-1)
shr al, bx
;przesun o odpowiednia wartosc
and al, 7
;zostawiamy tylko 3 najmlodsze bity
add al, 030h ;zamien na prawidlowy kod ASCII
mov ah, 0Eh ;wypisz
int 10h
loop petla
mov ah, 4Ch ;obie linijki powracaja do systemu
int 21h
8
binoct
ENDS ;zakoncz segment
END poczatek ;zakoncz wykonanie programu
27. Drukowanie napisu.
napis SEGMENT
ASSUME CS:napis, DS:napis, SS:napis
ORG 0100h
start:
mov bx, 05Dh ;przeniesienie napisu z pierwszego argumentu
petla: mov al, [bx] ;przeslanie znaku z nap do al
and al, al ;sprawdzenie czy znak to 0
jz koniec ;jesli 0 to koncze
mov ah, 0Eh ;jesli nie, drukuje znak
int 010h
inc bx ;bx++
jmp petla ;skok petli while
koniec:
mov ah, 04Ch ;zakonczenie
int 21h
nap DB "jakis inny napis",0
napis ENDS
END start
28. Drukuj imię.
DRUGI SEGMENT
ASSUME CS:DRUGI,DS:DRUGI,SS:DRUGI
ORG 0100H
MAIN:
mov al, [imie]
mov ah, 0Eh
int 10h
mov al, [imie+1]
mov ah, 0Eh
int 10h
mov al, [imie+2]
mov ah, 0Eh
int 10h
mov al, [imie+3]
mov ah, 0Eh
int 10h
mov al, [imie+4]
mov ah, 0Eh
int 10h
MOV AH, 4CH
INT 21H
imie DB "rafal"
DRUGI ENDS
END MAIN
9
mov al, [bx+1] ;wypisanie drugiej literki
mov ah, 0Eh ;wyswietlenie
int 10h
;ADRESOWANIE BAZOWE Z PRZEMIESZCZENIEM
mov bx, offset napis
mov al, [bx] ;wypisanie pierwszej literki
mov ah, 0Eh ;wyswietlenie
int 10h
inc bx ;zwiekszenie bx o 1 (inkrementacja)
mov al, [bx] ;wypisanie drugiej literki
mov ah, 0Eh ;wyswietlenie
int 10h
;ADRESOWANIE BAZOWO-INDEKSOWE
mov bx, offset napis
xor si, si
;wstawienie do si 0
mov al, [bx+si] ;pobranie pierwszej literki
mov ah, 0Eh ;wyswietlenie
int 10h
inc si
;zwiekszenie si o 1 (si++)
mov al, [bx+si] ;pobranie drugiej literki
mov ah, 0Eh ;wyswietlenie
int 10h
mov ah, 4Ch ;zakonczenie programu
int 21h
;tylko tu moga byc dane
napis DB "napis"
wydruk
ENDS
END start
32. Zamiana dużych liter na małe.
zamiana
SEGMENT
ASSUME CS:zamiana,DS:zamiana,SS:zamiana
ORG 0100h
start:
;dla zamiany duze na male -> or al, 020h
mov al, [napis]
xor al, 020h ;zamiana wielkosci literki
mov ah, 0Eh ;wyswietlenie
int 10h
mov al, [napis+1]
xor al, 020h ;zamiana wielkosci literki
mov ah, 0Eh ;wyswietlenie
int 10h
mov al, [napis+2]
xor al, 020h ;zamiana wielkosci literki
mov ah, 0Eh ;wyswietlenie
int 10h
mov al, [napis+3]
xor al, 020h ;zamiana wielkosci literki
mov ah, 0Eh ;wyswietlenie
int 10h
11
29. Drukuje znak.
znak SEGMENT
ASSUME CS:znak
ORG 0100h
main:
mov al, 4Dh ;znak hex
mov ah, 0Eh
int 10h
mov ah, 4Ch
int 21h
znak ENDS
END main
30. Pętla.
petla SEGMENT
ASSUME CS:petla,DS:petla,SS:petla
ORG 0100h
start:
mov bx, offset napis
;przeslanie napisu
xor si, si
;zerowanie licznika
mov cx, 5
;ilosc obiegow petli
p:
;poczatek petli
mov al, [bx+si]
mov ah, 0Eh
int 10h
inc si
;inkrementacja petli
loop p
;skok do p: i zmniejszenie cx o 1
;w domu: wydrukowac napis od
konca, albo od 5 do 1
mov ah, 4Ch
;zakonczenie programu
int 21h
napis DB "to jest jakis napis"
petla
ENDS
END start
31. Wydruk wykorzystujący indeksowanie.
wydruk
SEGMENT
ASSUME CS:wydruk,DS:wydruk,SS:wydruk
ORG 0100h
start:
;---skomentowane w dol bo moze dzialac tylko jedno adresowanie naraz---
;ADRESOWANIE BEZPOSREDNIE
mov al, [napis]
mov ah, 0Eh ;wyswietlenie
int 10h
mov al, [napis+1] ;wypisanie drugiej literki
mov ah, 0Eh ;wyswietlenie
int 10h
;ADRESOWANIE BAZOWE
mov bx, offset napis
mov al, [bx] ;wypisanie pierwszej literki
mov ah, 0Eh ;wyswietlenie
int 10h
10
mov ah, 4Ch ;zakonczenie programu
int 21h
;tylko tu moga byc dane
napis DB "nApIs"
zamiana
ENDS
END start
33. Drukuje bajt w postaci oktalnej.
exit MACRO
MOV AH, 4CH
INT 21H
ENDM
mlodsze MACRO
add al, 030h
mov ah, 0Eh
int 10h
ENDM
prog1
SEGMENT
ASSUME CS:prog1, DS:prog1, SS:prog1
ORG 0100H
MAIN:
mov al, 32
push ax
shr al, 2
;add al, 037h
mov ah, 0Eh
int 10h
pop ax
and al, 8
;cmp al, 10
;jb mlodsze2
;add al, 037h
mov ah, 0Eh
int 10h
;jmp koniec
exit
prog1 ENDS
END MAIN
12
1. Ile razy wykona się poniższa pętla.........................................................................................1
2. Jaki będzie wynik operacji......................................................................................................1
1
3. Napisać fragment programu drukujący (bez użycia funkcji BIOS/DOS) na środku ekranu
tekstowego literkę A..................................................................................................................1
4. Zrealizować w asemblerze konstrukcję switch.......................................................................1
5. Pokazać w jaki sposób bez użycia koprocesora można zrealizować działanie: AX=9*AX.......2
2
6. Co oznacza zapis xx DW 128 dup(255)..................................................................................2
7. Co znajdzie się w rejestrze ax po wykonaniu instrukcji..........................................................2
2
8. Napisać fragment kodu drukujący bezpośrednio na środku ekranu w trybie graficznym VGA
pojedynczy pikselek...................................................................................................................2
9. Napisz w jaki sposób można rozwiązać w assemblerze konstrukcje if – else..........................2
2
10. W komórce pamięci o adresie fizycznym 0x25394 znajduje się bajt. Napisać fragment
programu umożliwiający wczytanie go do rejestru al.................................................................2
11. Jak w asemblerze można zrealizować następujący fragment kodu języka C:
static int x;
if (x > 2) {wydrukuj znak 'A';}else{wydrukuj znak 'B'};............................................................3
12. W rejestrze al znajduje się bajt. Napisać fragment programu (lub jego schemat blokowy),
który zamienia ten bajt na postać czwórkową do wydruku na konsoli.......................................3
3
13. Przedstawić kompletną procedurę umożliwiającą obliczenie długości napisu, którego adres
znajduje się w rejestrze BX........................................................................................................3
14. Napisać fragment programu, który oblicza wartość delty równania kwadratowego o
współczynnikach rzeczywistych a, b i c.....................................................................................4
15. Napisać fragment programu, który drukuje na konsoli wszystkie małe litery ASCII.............4
4
16. Napisać kompletną procedurę, która zamienia kod ASCII (znajdujący się w rejestrze al)
małej litery na dużą (tj odpowiednik al=toupper(al))................................................................4
17. Napisać kompletne makro, które neguje 16 bitową liczbę całkowitą zawartą w rejestrze ax.
W jaki sposób zastosować to makro w programie......................................................................5
18. Jak w asemblerze można zrealizować następujący fragment kodu języka C:
static int x=1;
while (x<10) printf("%d\n",x++);..............................................................................................5
19. Napisać program typu COM, który odczytuje z klawiatury znaki oraz liczy ich ilość.
Wciśnięcie klawisza 'x' kończy program. Ilość wprowadzonych znaków ma znajdować się w
rejestrze ax................................................................................................................................5
20. Napisać program, w którym (1) zdefiniowano napis „zdane” zakończony znakiem powrotu
karetki. (2) napis ten należy wydrukować za pomocą procedury „drukowanie” znak po znaku
dużymi literami..........................................................................................................................6
21. Zrealizować w asemblerze fragment realizujący następujący kod w C:
for(i=1;i<10;i++)printf(„%d”,i);................................................................................................6
22. Napisać makro umożliwiające wprowadzanie z klawiatury jedynie cyfr z zakresu 0...9.......6
23. Jak wygląda stos procesora po niezależnym wykonaniu operacji a) int 21h, b) call
1234:5678, c) pop ax, d) DW 23, e) jmp 1234...........................................................................7
24. Atoi......................................................................................................................................7
25. Binhex.................................................................................................................................8
26. Binoct..................................................................................................................................8
27. Drukowanie napisu..............................................................................................................9
28. Drukuj imię..........................................................................................................................9
29. Drukuje znak.....................................................................................................................10
30. Pętla..................................................................................................................................10
31. Wydruk wykorzystujący indeksowanie..............................................................................10
1
32. Zamiana dużych liter na małe...........................................................................................11
33. Drukuje bajt w postaci oktalnej.........................................................................................12
0