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