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

1

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