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 |
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
Comments