Kilka algorytmów które mogą przydać się na przyszłość

1. Sprawdź, czy podany rok jest rokiem przestępnym (0-nie, 1-tak)
2. Na którym miejscu w tablicy jest pierwszy niezerowy element
3. To samo w nieco innej wersji (loope zamiast loop)
4. Sprawdź, czy wprowadzona liczba jest parzysta czy nie (pomocne w tym wypadku dzielenie zastąp przesuwaniem bitów w prawo. jeśli rejestr carry flag jest pusty-liczba parzysta, jeśli pełny-nieparzysta)
5. Podziel liczbę przez 3 bez użycia DIV
6. Policzyć, od ilu jedynek zaczyna się wprowadzona liczba w systemie dwójkowym. Program ma zwrócić ilość jedynek na początku. Np. przy liczbie 11001000 ma zwrócić 2. Gdy nie zaczyna się od jedynek ma zwrócić 0.
7. Wypełnij liczbę podaną w systemie dwójkowym jedynkami, ale tylko od momentu napotkania pierwszej (licząc od lewej strony) jedynki. Np. z liczby 00001010 zrób 00001111
8. Dodawanie dwóch parametrów z udziałem stosu
9. Ciąg Fibonacciego
10. Która liczba w tablicy pojawia się najczęściej
11. Czy podany punkt o współrzędnych x i y należy do okręgu o promieniu r, czyli czy spełnione jest równanie x^2+y^2

Sprawdź, czy podany rok jest rokiem przestępnym (0-nie, 1-tak)
C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include
using namespace std;
extern "C" {
unsigned short rok ;
unsigned short czy_przestepny;
void asm_main(void);
}
int main()
{
asm_main();
cout << czy_przestepny << endl;
system("PAUSE");
return 0;
}

ASM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
.386               ;Instrukcje procesora 80386
.MODEL FLAT, C     ;Model rozmieszczenia programu w pamieci (FLAT) i wywolywania funkcji (C)

EXTERN rok:WORD ;Zmienna zadeklarowana w innym module
EXTERN czy_przestepny:WORD

.CODE              ;Poczatek segmentu przeznaczonego na instrukcje

asm_main PROC      ;Definicja procedury (funkcji) "asm_main"

mov dx,0
mov rok, 2100
mov ax,rok
mov bx,4
div bx
cmp dx,0
jne nieprzestepny
mov czy_przestepny,1

mov ax, rok
mov bx,100
div bx
cmp dx,0
jne przestepny

mov ax, rok
mov bx,400
div bx
cmp dx,0
jne nieprzestepny

przestepny:
mov czy_przestepny, 1
jmp koniec
nieprzestepny:
mov czy_przestepny,0

koniec:
ret
asm_main ENDP
END

Na którym miejscu w tablicy jest pierwszy niezerowy element
C++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include
using namespace std;

extern "C" {
unsigned short liczba;
int asm_main(void);
int a[8] = {0,0,0,0,2,5,7,9};
int rozmiar=8;
int wynik;
}
int main()
{

int wynik=asm_main();//wynik zostanie pobrany z eax
cout << wynik << endl;
system("PAUSE");
return 0;
}

ASM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.386               ;Instrukcje procesora 80386
.MODEL FLAT, C     ;Model rozmieszczenia programu w pamieci (FLAT) i wywolywania funkcji (C)

EXTERN liczba:WORD ;Zmienna zadeklarowana w innym module
EXTERN a: SDWORD
EXTERN rozmiar:SDWORD

.CODE              ;Poczatek segmentu przeznaczonego na instrukcje
; na ktorym miejscu w tablicy jest pierwszy niezerowy element

asm_main PROC      ;Definicja procedury (funkcji) "asm_main"

mov ECX, rozmiar
petla:
mov EAX, rozmiar
sub eax, ecx
cmp a[eax*4], 0
jne koniec
loop petla
koniec:

ret             ;Powrot z funkcji
asm_main ENDP
END

To samo w nieco innej wersji (loope zamiast loop)
C++ tak samo jak wyżej
ASM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.386               ;Instrukcje procesora 80386
.MODEL FLAT, C     ;Model rozmieszczenia programu w pamieci (FLAT) i wywolywania funkcji (C)

EXTERN liczba:WORD ;Zmienna zadeklarowana w innym module
EXTERN a: SDWORD
EXTERN rozmiar:SDWORD

.CODE              ;Poczatek segmentu przeznaczonego na instrukcje
; na ktorym miejscu w tablicy jest pierwszy niezerowy element

asm_main PROC      ;Definicja procedury (funkcji) "asm_main"

mov ECX, rozmiar
petla:
mov eax, rozmiar
sub eax, ecx
cmp a[eax*4], 0

loope petla
koniec:

ret             ;Powrot z funkcji
asm_main ENDP
END

Sprawdź, czy wprowadzona liczba jest parzysta czy nie (pomocne w tym wypadku dzielenie zastąp przesuwaniem bitów w prawo. jeśli rejestr carry flag jest pusty-liczba parzysta, jeśli pełny-nieparzysta)
C++

1
2
3
4
5
6
7
8
9
10
11
12
13
#include
using namespace std;
extern "C" {
int liczba = 11;
void asm_main(void);
int czy_parzysta;
}

int main()
{
asm_main();
return 0;
}

ASM v1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
.386               ;Instrukcje procesora 80386
.MODEL FLAT, C     ;Model rozmieszczenia programu w pamieci (FLAT) i wywolywania funkcji (C)

EXTERN liczba:WORD ;Zmienna zadeklarowana w innym module
EXTERN czy_parzysta:SDWORD

.CODE              ;Poczatek segmentu przeznaczonego na instrukcje

asm_main PROC      ;Definicja procedury (funkcji) "asm_main"
shr liczba, 1   ; rotate right
jnc parzysta        ; if not carry flag
mov czy_parzysta, 0
jmp koniec
parzysta:
mov czy_parzysta, 1
koniec:
ret             ;Powrot z funkcji
asm_main ENDP
END

ASM v2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
.386               ;Instrukcje procesora 80386
.MODEL FLAT, C     ;Model rozmieszczenia programu w pamieci (FLAT) i wywolywania funkcji (C)

EXTERN liczba:WORD ;Zmienna zadeklarowana w innym module
EXTERN czy_parzysta:SDWORD

.CODE              ;Poczatek segmentu przeznaczonego na instrukcje

asm_main PROC      ;Definicja procedury (funkcji) "asm_main"
shr liczba, 1
setnc al        ; set if not carry flag
mov ah, 0
movzx ebx, al  ; movzx umożliwia przeniesienie mniejszego rejestru do większego
mov czy_parzysta, ebx

ret             ;Powrot z funkcji
asm_main ENDP
END

Podziel liczbę przez 3 bez użycia DIV.
C++

1
2
3
4
5
6
7
8
9
10
11
12
13
#include
using namespace std;
extern "C" {
int liczba = 6;
void asm_main(void);
int wynik;
}

int main()
{
asm_main();
return 0;
}

ASM (coś tu nie działa)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
.386               ;Instrukcje procesora 80386
.MODEL FLAT, C     ;Model rozmieszczenia programu w pamieci (FLAT) i wywolywania funkcji (C)

EXTERN liczba:WORD ;Zmienna zadeklarowana w innym module
EXTERN wynik:SDWORD

.CODE              ;Poczatek segmentu przeznaczonego na instrukcje

asm_main PROC      ;Definicja procedury (funkcji) "asm_main"
mov eax, liczba
shl eax, 3
sub eax, liczba
mov wynik, eax
ret             ;Powrot z funkcji
asm_main ENDP
END

Policzyć, od ilu jedynek zaczyna się wprowadzona liczba w systemie dwójkowym. Program ma zwrócić ilość jedynek na początku. Np. przy liczbie 11001000 ma zwócić 2. Gdy nie zaczyna się od jedynek ma zwrócić 0
C++

1
2
3
4
5
6
7
8
9
10
11
12
13
#include
using namespace std;
extern "C" {
int liczba = 2;
void asm_main(void);
int wynik;
}

int main()
{
asm_main();
return 0;
}

ASM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.386               ;Instrukcje procesora 80386
.MODEL FLAT, C     ;Model rozmieszczenia programu w pamieci (FLAT) i wywolywania funkcji (C)

EXTERN liczba:BYTE ;Zmienna zadeklarowana w innym module
EXTERN wynik:WORD

.CODE              ;Poczatek segmentu przeznaczonego na instrukcje

asm_main PROC      ;Definicja procedury (funkcji) "asm_main"
mov al, liczba
mov wynik, 0

petla:
shl al, 1
jc koniec   ; wg psora tu powinno być jnc wg mnie jc
add wynik, 1 ;wynik pełni tutaj funkcje licznika - ile razy NIE skoczylismy poleceniem jnc koniec
jmp petla
koniec:

ret             ;Powrot z funkcji
asm_main ENDP
END

Wypełnij liczbę podaną w systemie dwójkowym jedynkami, ale tylko od momentu napotkania pierwszej (licząc od lewej strony) jedynki. Np. z liczby 00001010 zrób 00001111 nie jestem pewien czy dobrze działa
C++

1
2
3
4
5
6
7
8
9
10
11
12
13
#include
using namespace std;
extern "C" {
unsigned char liczba = 129;
void asm_main(void);
int wynik;
}

int main()
{
asm_main();
return 0;
}

ASM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.386               ;Instrukcje procesora 80386
.MODEL FLAT, C     ;Model rozmieszczenia programu w pamieci (FLAT) i wywolywania funkcji (C)

EXTERN liczba:BYTE ;Zmienna zadeklarowana w innym module
EXTERN wynik:WORD

.CODE              ;Poczatek segmentu przeznaczonego na instrukcje

asm_main PROC      ;Definicja procedury (funkcji) "asm_main"
mov ecx, 9
mov al, 0
petla:
cmp al, 1
rcl liczba, 1 ; przewijamy liczbe o 1
jnc jeszcze_zero
mov al, 1
jeszcze_zero:

loop petla

ret             ;Powrot z funkcji
asm_main ENDP
END

Dodawanie dwóch parametrow z udzialem stosu
C++

1
2
3
4
5
6
7
8
9
10
11
12
#include
using namespace std;
extern "C" {
//unsigned short liczba;
int asm_main(int a, int b);
}

int main()
{
int r=asm_main(4,3);
return 0;
}

ASM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.386               ;Instrukcje procesora 80386
.MODEL FLAT, C     ;Model rozmieszczenia programu w pamieci (FLAT) i wywolywania funkcji (C)

;EXTERN liczba:WORD ;Zmienna zadeklarowana w innym module

.CODE              ;Poczatek segmentu przeznaczonego na instrukcje

asm_main PROC      ;Definicja procedury (funkcji) "asm_main"
push ebp ; !!
mov ebp, esp ;!
mov eax, [ebp+8]
add eax, [ebp+12]

pop ebp ;!!
ret             ;Powrot z funkcji
asm_main ENDP
END

Ciąg fibonacciego
C++

1
2
3
4
5
6
7
8
9
10
11
#include
using namespace std;
extern "C" {
int funkcja(int liczba);
}

int main()
{
int wynik=funkcja(7);
return 0;
}

ASM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
.386               ;Instrukcje procesora 80386
.MODEL FLAT, C     ;Model rozmieszczenia programu w pamieci (FLAT) i wywolywania funkcji (C)

.CODE              ;Poczatek segmentu przeznaczonego na instrukcje

funkcja PROC      ;Definicja procedury  funkcja
push ebp
mov ebp, esp
cmp dword ptr[ebp+8], 2
jnb el
mov eax, 1
jmp koniec
el:
mov edx, [ebp+8]
sub edx, 1
push edx
call funkcja
add esp, 4 ; lub pop edx
push eax
mov edx, [ebp+8]
sub edx, 2
push edx
call funkcja
add esp, 4;pop edx zrobi to samo
pop edx
add eax, edx
koniec:
pop ebp
ret             ;Powrot z funkcji
funkcja ENDP
END

Która liczba w tablicy pojawia się najczęściej
C++

1
2
3
4
5
6
7
8
9
10
11
12
13
#include
using namespace std;
extern "C" {
unsigned char asm_main();
unsigned int tablica [9]={1, 2, 3, 1, 4, 1, 3, 1, 5};
int ile=9;
unsigned char ilosci[8];
}
int main()
{
unsigned char najczestsza=asm_main();
return 0;
}

ASM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
.386               ;Instrukcje procesora 80386
.MODEL FLAT, C     ;Model rozmieszczenia programu w pamieci (FLAT) i wywolywania funkcji (C)

EXTERN ile: SDWORD ;Zmienna zadeklarowana w innym module
EXTERN tablica: DWORD
EXTERN ilosci: BYTE ;tablica ilosci przechowuje informacje o tym ile razy w tablicy tablica
; dany element wystepuje. po jej wypelnieniu musimy na tej tablicy zastosowac
;poznana wczesniej procedure wyszukiwania najwiekszego elementu
;w tablicy
.CODE              ;Poczatek segmentu przeznaczonego na instrukcje

asm_main PROC      ;Definicja procedury (funkcji) "asm_main"
mov ecx, ile ; licznik petli
petla: ;petla liczaca ile razy wystapeuje dany element w tablicy
mov eax,tablica [ecx*4+4]
inc ilosci[eax]
loop petla
mov ecx, 8
petla2: ; szukamy informacji o tym, ile razy ten najczesciej powtarzajacy
;sie element wystepuje. nie wiemy jeszcze jednak jaka to liczba
cmp dl, ilosci[ecx-1]
jg dalej
mov dl, ilosci[ecx-1]
mov eax, ecx;zapamietuje dokładnie jaka
sub eax, 1 ;liczba jest ta najczestsza. wynik laduje w eax

dalej:

loop petla2
ret
asm_main ENDP
END

Czy podany punkt o współrzędnych x i y należy do okręgu o promieniu r, czyli czy spełnione jest równanie x^2+y^2
C++

1
dopisać

ASM

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
.386               ;Instrukcje procesora 80386
.MODEL FLAT, C     ;Model rozmieszczenia programu w pamieci (FLAT) i wywolywania funkcji (C)</strong>

<strong> </strong>

.CODE              ;Poczatek segmentu przeznaczonego na instrukcje

asm_main PROC      ;Definicja procedury (funkcji) "asm_main"
push ebp ; x jest pod adresem [ebp+8], y pod [ebp+12], a r pod [ebp+16]
mov ebp, esp
mov eax, [ebp+8] ;kazdy parametr (x, y i r) wrzucamy po kolei do eax
;i wykonujemy na nim dzialanie
mul eax
mov ecx, eax
mov eax, [ebp+12]
mul eax
add ecx, eax
mov eax, [ebp+16]
mul eax
cmp eax, ecx
jg r_wiekszy
mov eax, 0
jmp koniec
r_wiekszy:
mov eax, 1
koniec:
pop ebp
ret

pop ebp
ret
asm_main ENDP
END

Polecam:
wikibooks instrukcje procesora
podstawowe funkcje 4programmers